3
Z_ð]uF  ã               @   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m	Z	m
Z
 d dlmZ d dlZdddddd	d
dddg
ZdZee je je jfƒZed e jfƒZejdd… dkr¼eje jƒ ejrÈejZejjdƒjZej j!ej ƒZ"dd„ Z#dd„ Z$dd„ Z%ejdd… dk�r6ee j&e jfƒZ'ee j(e j)e j*fƒZ+n(ee j&e je j)fƒZ'ee j(e j*e j,fƒZ+dd„ Z-yd dlm.Z. W n e/k
�r’   e0ƒ Z.Y nX G dd„ de0ƒZ1dd„ Z2dZ3yd dl4m5Z5 W n& e/k
�ræ   G dd„ de0ƒZ5Y nX d d„ Z6dS )!é    N)Ú
trampolineÚnotify_openedÚIOClosed)Ú	get_errnoÚGreenSocketÚ_GLOBAL_DEFAULT_TIMEOUTÚset_nonblockingÚSOCKET_BLOCKINGÚSOCKET_CLOSEDÚCONNECT_ERRÚCONNECT_SUCCESSÚshutdown_safeÚSSLÚsocket_timeouti   é   ÚwinÚsocketc             C   s4   | j |ƒ}|tkrdS |tkr0tj|tj| ƒ‚| S )z›
    Attempts to connect to the address, returns the descriptor if it succeeds,
    returns None if it needs to trampoline, and raises any exceptions.
    N)Ú
connect_exr   r   r   ÚerrorÚerrnoÚ	errorcode)Ú
descriptorÚaddressÚerr© r   ú9/tmp/pip-build-yz_zf6az/eventlet/eventlet/greenio/base.pyÚsocket_connect#   s    
r   c             C   s.   | j tjtjƒ}|tkr*tj|tj| ƒ‚d S )N)Ú
getsockoptr   Ú
SOL_SOCKETÚSO_ERRORr   r   r   r   )r   r   r   r   r   Úsocket_checkerr0   s    r    c             C   sF   y| j ƒ S  tjk
r@ } zt|ƒtjkr.dS ‚ W Y dd}~X nX dS )z«
    Attempts to accept() on the descriptor, returns a client,address tuple
    if it succeeds; returns None if it needs to trampoline, and raises
    any exceptions.
    N)Úacceptr   r   r   r   ÚEWOULDBLOCK)r   Úer   r   r   Úsocket_accept6   s    r$   c             C   sŽ   y
| j }W nv tk
r€   yddl}W n tk
rB   tdƒ‚Y nX | jƒ }|j||jƒ}|tjB }||kr||j||j	|ƒ Y n
X |dƒ dS )z£
    Sets the descriptor to be nonblocking.  Works on many file-like
    objects as well as sockets.  Only sockets can be nonblocking on
    Windows, however.
    r   Nznset_nonblocking() on a file object with no setblocking() method (Windows pipes don't support non-blocking I/O))
ÚsetblockingÚAttributeErrorÚfcntlÚImportErrorÚNotImplementedErrorÚfilenoÚF_GETFLÚosÚ
O_NONBLOCKÚF_SETFL)Úfdr%   r'   r*   Z
orig_flagsZ	new_flagsr   r   r   r   O   s    

)r   c               @   sP  e Zd ZdZdZejfdd„Zedd„ ƒZ	e
jrJdd„ Zd	d
„ ZeeeƒZdd„ ZdEdd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Ze
jrœdd„ Zndd„ Zdd „ Zd!d"„ Zd#d$„ ZdFd&d'„ZdGd(d)„ZdHd*d+„ZdId,d-„Zd.d/„ ZdJd0d1„Z d2d3„ Z!dKd4d5„Z"d6d7„ Z#d8d9„ Z$d:d;„ Z%d<d=„ Z&d>d?„ Z'd@e(j)k�rLdAdB„ Z*dCdD„ Z+dS )Lr   a  
    Green version of socket.socket class, that is intended to be 100%
    API-compatible.

    It also recognizes the keyword parameter, 'set_nonblocking=True'.
    Pass False to indicate that socket is already in non-blocking mode
    to save syscalls.
    Nc             O   sÞ   |j ddƒ}t|tjƒr6t|f|ž|Ž}t|jƒ ƒ n|}y|jƒ pJtj	ƒ | _
W n tk
rn   tj	ƒ | _
Y nX |rˆ|jƒ dkrˆt|ƒ || _d| _|j| _|j| _|j| _|j| _|j| _|j| _|j| _|j| _d| _d S )Nr   Té   Féÿÿÿÿ)ÚpopÚ
isinstanceÚsixÚinteger_typesÚ_original_socketr   r*   Ú
gettimeoutr   ÚgetdefaulttimeoutÚ_timeoutr&   r   r/   Úact_non_blockingÚbindÚcloseÚgetsocknamer   ÚlistenÚ
setsockoptÚshutdownÚ_closed)ÚselfÚfamilyÚargsÚkwargsZshould_set_nonblockingr/   r   r   r   Ú__init__…   s,    zGreenSocket.__init__c             C   s   | S )Nr   )rB   r   r   r   Ú_sock¬   s    zGreenSocket._sockc             C   s   | j jS )N)r/   Ú_io_refs)rB   r   r   r   Ú_get_io_refs±   s    zGreenSocket._get_io_refsc             C   s   || j _d S )N)r/   rH   )rB   Úvaluer   r   r   Ú_set_io_refs´   s    zGreenSocket._set_io_refsc             C   s.   | j d krt|ƒ‚t| j |ƒ}t| ||ƒ |S )N)r/   r&   ÚgetattrÚsetattr)rB   ÚnameÚattrr   r   r   Ú__getattr__¾   s
    
zGreenSocket.__getattr__Fc             C   sF   | j rtƒ ‚yt|||||| jd�S  tk
r@   | jƒ  ‚ Y nX dS )zí We need to trampoline via the event hub.
            We catch any signal back from the hub indicating that the operation we
            were waiting on was associated with a filehandle that's since been
            invalidated.
        )ÚreadÚwriteÚtimeoutÚtimeout_excZmark_as_closedN)rA   r   r   Ú_mark_as_closed)rB   r/   rQ   rR   rS   rT   r   r   r   Ú_trampolineÅ   s    

zGreenSocket._trampolinec             C   sŽ   | j r$| jjƒ }t|d jƒ ƒ |S | j}tdƒ}xVt|ƒ}|d k	rp|\}}t|jƒ ƒ t|ƒ t| ƒ|ƒ|fS | j	|d| j
ƒ |d� q4W d S )Nr   z	timed outT)rQ   rS   rT   )r:   r/   r!   r   r*   r   r$   r   ÚtyperV   r7   )rB   Úresr/   Ú_timeout_excÚclientÚaddrr   r   r   r!   Ø   s    
zGreenSocket.acceptc             C   s
   d| _ dS )z" Mark this socket as being closed TN)rA   )rB   r   r   r   rU   è   s    zGreenSocket._mark_as_closedc             C   s   t | dd ƒ}|d k	r|ƒ  d S )Nr<   )rL   )rB   r<   r   r   r   Ú__del__ì   s    zGreenSocket.__del__c             C   sþ   | j r| jj|ƒS | j}tdƒ}| jƒ d krzxÌt||ƒsvy| j|dd� W n  tk
rj   tj	t
jƒ‚Y nX t|ƒ q.W n€tjƒ | jƒ  }xnt||ƒršd S tjƒ |krª|‚|tjƒ  }y| j|d||d� W n  tk
rì   tj	t
jƒ‚Y nX t|ƒ qŒW d S )Nz	timed outT)rR   )rR   rS   rT   )r:   r/   Úconnectr   r7   r   rV   r   r   r   r   ÚEBADFDr    Útime)rB   r   r/   rY   ÚendrS   r   r   r   r]   ò   s.    
zGreenSocket.connectc             C   s6  | j r| jj|ƒS | j}| jƒ d krŒxdt||ƒsˆy| j|dd� t|ƒ W q& tjk
rp } zt	|ƒS d }~X q& t
k
r„   tjS X q&W n¦tjƒ | jƒ  }tjtjƒ}xˆyDt||ƒrºdS tjƒ |krÊ|‚| j|d|tjƒ  |d� t|ƒ W qª tjk
�r } zt	|ƒS d }~X qª t
k
�r,   tjS X qªW d S )NT)rR   r   )rR   rS   rT   )r:   r/   r   r7   r   rV   r    r   r   r   r   r   r^   r_   rS   ÚEAGAIN)rB   r   r/   Úexr`   rT   r   r   r   r     s6    
zGreenSocket.connect_exc             O   s0   | j j||Ž}t| ƒ|dd�}|j| jƒ ƒ |S )NF)r   )r/   ÚduprW   Ú
settimeoutr7   )rB   rD   ÚkwÚsockÚnewsockr   r   r   rc   +  s    zGreenSocket.dupc             O   s   t j| f|ž|ŽS )N)r6   Úmakefile)rB   rD   rE   r   r   r   rh   2  s    zGreenSocket.makefilec             O   s4   | j ƒ }t|f|ž|Ž}t|dƒr0|jƒ  d |_|S )NÚ_drop)rc   Ú_python2_fileobjectÚhasattrri   r<   )rB   rD   rE   ZduppedrX   r   r   r   rh   5  s    
c             O   s   t jdtdd� | j||ŽS )Nz>makeGreenFile has been deprecated, please use makefile insteadé   )Ú
stacklevel)ÚwarningsÚwarnÚDeprecationWarningrh   )rB   rD   re   r   r   r   ÚmakeGreenFileA  s    
zGreenSocket.makeGreenFilec             C   s    | j | jd| jƒ tdƒd� d S )NTz	timed out)rQ   rS   rT   )rV   r/   r7   r   )rB   r   r   r   Ú_read_trampolineF  s
    zGreenSocket._read_trampolinec             G   s²   | j }| jr||Ž S x˜y|d s(| jƒ  ||Ž S  tjk
rr } z&t|ƒtkrPnt|ƒtkr`|S ‚ W Y d d }~X nX y| jƒ  W q tk
r¨ } zt	ƒ ‚W Y d d }~X qX qW d S )Nr   )
r/   r:   rr   r   r   r   r	   r
   r   ÚEOFError)rB   Z	recv_methZ	empty_valrD   r/   r#   r   r   r   Ú
_recv_loopM  s$    	zGreenSocket._recv_loopr   c             C   s   | j | jjd||ƒS )Nó    )rt   r/   Úrecv)rB   ÚbufsizeÚflagsr   r   r   rv   m  s    zGreenSocket.recvc             C   s   | j | jjd||ƒS )Nru   )rt   r/   Úrecvfrom)rB   rw   rx   r   r   r   ry   p  s    zGreenSocket.recvfromc             C   s   | j | jjd|||ƒS )Nr   )rt   r/   Ú	recv_into)rB   ÚbufferÚnbytesrx   r   r   r   rz   s  s    zGreenSocket.recv_intoc             C   s   | j | jjd|||ƒS )Nr   )rt   r/   Úrecvfrom_into)rB   r{   r|   rx   r   r   r   r}   v  s    zGreenSocket.recvfrom_intoc             G   s¶   | j r||f|žŽ S tdƒ}x”y||f|žŽ S  tjk
rl } z"t|ƒ}|tjksZ|tkr\‚ W Y d d }~X nX y| j| j	d| j
ƒ |d� W q tk
r¬   tjtjdƒ‚Y qX qW d S )Nz	timed outT)rR   rS   rT   z#Connection closed by another thread)r:   r   r   r   r   r   ÚENOTCONNr	   rV   r/   r7   r   Ú
ECONNRESET)rB   Zsend_methodÚdatarD   rY   r#   Zenor   r   r   Ú
_send_loopy  s    zGreenSocket._send_loopc             C   s   | j | jj||ƒS )N)r�   r/   Úsend)rB   r€   rx   r   r   r   r‚   Œ  s    zGreenSocket.sendc             G   s   | j | jj|f|žŽ S )N)r�   r/   Úsendto)rB   r€   rD   r   r   r   rƒ   �  s    zGreenSocket.sendtoc             C   s>   | j ||ƒ}t|ƒ}x$||k r8|| j ||d … |ƒ7 }qW d S )N)r‚   Úlen)rB   r€   rx   ÚtailZlen_datar   r   r   Úsendall’  s    
zGreenSocket.sendallc             C   s"   |rd| _ d | _nd| _ d| _d S )NFTg        )r:   r9   )rB   Úflagr   r   r   r%   ˜  s
    zGreenSocket.setblockingc             C   s‚   |d ks|t kr| jdƒ d S y
|j}W n tk
rD   tdƒ‚Y nX |ƒ }|dk r\tdƒ‚|dkrrd| _d| _nd| _|| _d S )NTza float is requiredg        zTimeout value out of rangeF)r   r%   Ú	__float__r&   Ú	TypeErrorÚ
ValueErrorr:   r9   )rB   ZhowlongÚfr   r   r   rd      s    

zGreenSocket.settimeoutc             C   s   | j S )N)r9   )rB   r   r   r   r7   ²  s    zGreenSocket.gettimeoutc             C   s   | S )Nr   )rB   r   r   r   Ú	__enter__µ  s    zGreenSocket.__enter__c             G   s   | j ƒ  d S )N)r<   )rB   rD   r   r   r   Ú__exit__¸  s    zGreenSocket.__exit__Z__pypy__c             C   s   t | jd| jƒjƒ  d S )NrG   )rL   r/   Ú_reuse)rB   r   r   r   rŽ   ¼  s    zGreenSocket._reusec             C   s   t | jd| jƒjƒ  d S )NrG   )rL   r/   ri   )rB   r   r   r   ri   ¿  s    zGreenSocket._drop)FFNN)r   )r   )r   r   )r   r   )r   )r   ),Ú__name__Ú
__module__Ú__qualname__Ú__doc__r/   r   ÚAF_INETrF   ÚpropertyrG   r4   ÚPY3rI   rK   rH   rP   rV   r!   rU   r\   r]   r   rc   rh   rq   rr   rt   rv   ry   rz   r}   r�   r‚   rƒ   r†   r%   rd   r7   rŒ   r�   ÚsysÚbuiltin_module_namesrŽ   ri   r   r   r   r   r   x   sL   '


 





c              O   s   t dƒ‚d S )NzI/O operation on closed file)rŠ   )rD   rE   r   r   r   Ú_operation_on_closed_fileÃ  s    r˜   a  
    GreenPipe is a cooperative replacement for file class.
    It will cooperate on pipes. It will block on regular file.
    Differneces from file class:
    - mode is r/w property. Should re r/o
    - encoding property not implemented
    - write/writelines will not raise TypeError exception when non-string data is written
      it will write str(data) instead
    - Universal new lines are not supported and newlines property not implementeded
    - file argument can be descriptor, file name or file object.
    )r   c               @   sL   e Zd ZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZd	S )
r   c               @   s   e Zd ZdS )zSSL.WantWriteErrorN)r�   r�   r‘   r   r   r   r   ÚWantWriteErrorÙ  s   r™   c               @   s   e Zd ZdS )zSSL.WantReadErrorN)r�   r�   r‘   r   r   r   r   ÚWantReadErrorÜ  s   rš   c               @   s   e Zd ZdS )zSSL.ZeroReturnErrorN)r�   r�   r‘   r   r   r   r   ÚZeroReturnErrorß  s   r›   c               @   s   e Zd ZdS )zSSL.SysCallErrorN)r�   r�   r‘   r   r   r   r   ÚSysCallErrorâ  s   rœ   N)r�   r�   r‘   Ú	Exceptionr™   rš   r›   rœ   r   r   r   r   r   Ø  s   c             C   sn   y*y| j tjƒS  tk
r&   | j ƒ S X W n> tjk
rh } z t|ƒtjtjtj	fkrX‚ W Y dd}~X nX dS )a¥  Shuts down the socket. This is a convenience method for
    code that wants to gracefully handle regular sockets, SSL.Connection
    sockets from PyOpenSSL and ssl.SSLSocket objects from Python 2.7 interchangeably.
    Both types of ssl socket require a shutdown() before close,
    but they have different arity on their shutdown method.

    Regular sockets don't need a shutdown before close, but it doesn't hurt.
    N)
r@   r   Ú	SHUT_RDWRr‰   r   r   r   r~   ÚEBADFZENOTSOCK)rf   r#   r   r   r   r   æ  s    	)7r   r,   r   r–   r_   rn   ZeventletZeventlet.hubsr   r   r   Zeventlet.supportr   r4   Ú__all__ÚBUFFER_SIZEÚsetZEINPROGRESSZEALREADYr"   r   ZEISCONNr   ÚplatformÚaddZ	WSAEINVALÚPY2Z_fileobjectrj   ZpatcherÚoriginalr6   rS   Zwrap_is_timeoutr   r   r    r$   ra   r	   r   r~   Z	ESHUTDOWNr
   ÚEPIPEr   r   r(   Úobjectr   r˜   Zgreenpipe_docZOpenSSLr   r   r   r   r   r   Ú<module>   sZ   #  M