a
    äzelF  ã                   @   s  d 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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lmZ ejdd„ ƒZe eedƒd¡G d	d
„ d
ejƒƒZe eedƒd¡G dd„ deƒƒZe eedƒd¡G dd„ deƒƒZe eedƒd¡G dd„ deƒƒZe eedƒd¡e eedƒd¡G dd„ deƒƒƒZe eedƒd¡G dd„ deƒƒZG dd„ deƒZedkrŒe ¡  dS )a±  
This test suite exercises some system calls subject to interruption with EINTR,
to check that it is actually handled transparently.
It is intended to be run by the main test suite within a child process, to
ensure there is no background thread running (so that signals are delivered to
the correct thread).
Signals are generated in-process using setitimer(ITIMER_REAL), which allows
sub-second periodicity (contrarily to signal()).
é    N)Úsupport)Úsocket_helperc                 c   sJ   | 2 z
| V  W n   |   ¡  ‚ Y n0 W d  ƒ n1 s<0    Y  dS )zGContext manager killing the subprocess if a Python exception is raised.N)Úkill)Úproc© r   ú1/usr/lib/python3.9/test/eintrdata/eintr_tester.pyÚkill_on_error   s    
r   Ú	setitimerzrequires setitimer()c                   @   sH   e Zd ZdZdZdZdZdd„ Zdd„ Ze	dd	„ ƒZ
d
d„ Zdd„ ZdS )ÚEINTRBaseTestz Base class for EINTR tests. gš™™™™™¹?gš™™™™™É?c                 C   s   |  j d7  _ d S ©Né   )Úsignals)ÚselfÚsignumÚframer   r   r   Ú
sighandler2   s    zEINTRBaseTest.sighandlerc                 C   sB   d| _ t tj| j¡| _t tj| j| j¡ t	j
ddtjd d S )Nr   iX  T)ÚexitÚfile)r   ÚsignalÚSIGALRMr   Úorig_handlerr	   ÚITIMER_REALÚsignal_delayÚsignal_periodÚfaulthandlerZdump_traceback_laterÚsysÚ
__stderr__©r   r   r   r   ÚsetUp5   s    ÿÿzEINTRBaseTest.setUpc                   C   s   t  t jdd¡ d S ©Nr   )r   r	   r   r   r   r   r   Ú
stop_alarm@   s    zEINTRBaseTest.stop_alarmc                 C   s$   |   ¡  t tj| j¡ t ¡  d S ©N)r    r   r   r   r   Zcancel_dump_traceback_laterr   r   r   r   ÚtearDownD   s    zEINTRBaseTest.tearDownc                 O   s    t jdf| }tj|fi |¤ŽS )Nz-c)r   Ú
executableÚ
subprocessÚPopen)r   ÚargsÚkwZcmd_argsr   r   r   r$   I   s    zEINTRBaseTest.subprocessN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   Ú
sleep_timer   r   Ústaticmethodr    r"   r$   r   r   r   r   r
   &   s   
r
   c                   @   s|   e Zd ZdZdd„ Zdd„ Zdd„ Ze e	e
dƒd	¡d
d„ ƒZdd„ Zdd„ Ze e	e
dƒd¡dd„ ƒZdd„ Zdd„ ZdS )ÚOSEINTRTestz  EINTR tests for the os module. c                 C   s   d| j  }|  |¡S )Nzimport time; time.sleep(%r))r,   r$   )r   Úcoder   r   r   Únew_sleep_processR   s    
zOSEINTRTest.new_sleep_processc                    sD   d}‡ fdd„t |ƒD ƒ}t |ƒD ]
}|ƒ  q"|D ]}| ¡  q2d S )Né   c                    s   g | ]}ˆ   ¡ ‘qS r   )r0   )Ú.0Ú_r   r   r   Ú
<listcomp>X   ó    z3OSEINTRTest._test_wait_multiple.<locals>.<listcomp>)ÚrangeÚwait)r   Ú	wait_funcÚnumÚ	processesr3   r   r   r   r   Ú_test_wait_multipleV   s    zOSEINTRTest._test_wait_multiplec                 C   s   |   tj¡ d S r!   )r;   Úosr7   r   r   r   r   Ú	test_wait_   s    zOSEINTRTest.test_waitÚwait3zrequires wait3()c                 C   s   |   dd„ ¡ d S )Nc                   S   s
   t  d¡S r   )r<   r>   r   r   r   r   Ú<lambda>d   r5   z(OSEINTRTest.test_wait3.<locals>.<lambda>)r;   r   r   r   r   Ú
test_wait3b   s    zOSEINTRTest.test_wait3c                 C   s   |   ¡ }||jƒ | ¡  d S r!   )r0   Úpidr7   )r   r8   r   r   r   r   Ú_test_wait_singlef   s    
zOSEINTRTest._test_wait_singlec                 C   s   |   dd„ ¡ d S )Nc                 S   s   t  | d¡S r   )r<   Úwaitpid©rA   r   r   r   r?   m   r5   z*OSEINTRTest.test_waitpid.<locals>.<lambda>©rB   r   r   r   r   Útest_waitpidl   s    zOSEINTRTest.test_waitpidÚwait4zrequires wait4()c                 C   s   |   dd„ ¡ d S )Nc                 S   s   t  | d¡S r   )r<   rG   rD   r   r   r   r?   q   r5   z(OSEINTRTest.test_wait4.<locals>.<lambda>rE   r   r   r   r   Ú
test_wait4o   s    zOSEINTRTest.test_wait4c                 C   sÈ   t  ¡ \}}|  t j|¡ g d¢}d dddd| d| j ddd	d
df
¡}| j|t|ƒ|gd}t|ƒL t  |¡ |D ]}|  	|t  
|t|ƒ¡¡ qx|  	| ¡ d¡ W d   ƒ n1 sº0    Y  d S )N)s   hellos   worlds   spamÚ
zimport os, sys, timeÚ zwr = int(sys.argv[1])ú
datas = %rúsleep_time = %rzfor data in datas:z$    # let the parent block on read()ú    time.sleep(sleep_time)z    os.write(wr, data)©Úpass_fdsr   )r<   ÚpipeÚ
addCleanupÚcloseÚjoinr,   r$   Ústrr   ÚassertEqualÚreadÚlenr7   )r   ÚrdÚwrÚdatasr/   r   Údatar   r   r   Ú	test_reads   s*    ö

zOSEINTRTest.test_readc                 C   sê   t  ¡ \}}|  t j|¡ dtj }d dddd| j dtj ddd	d
ddddddddddf¡}| j|t	|ƒ|gd}t
|ƒX t  |¡ d}|t|ƒk r¸|t  |t|ƒ|d … ¡7 }qŽ|  | ¡ d¡ W d   ƒ n1 sÜ0    Y  d S )Nó   xrI   zimport io, os, sys, timerJ   zrd = int(sys.argv[1])rL   zdata = b"x" * %súdata_len = len(data)z!# let the parent block on write()útime.sleep(sleep_time)zread_data = io.BytesIO()z+while len(read_data.getvalue()) < data_len:z%    chunk = os.read(rd, 2 * data_len)z    read_data.write(chunk)zvalue = read_data.getvalue()zif value != data:z0    raise Exception("read error: %s vs %s bytes"z-                    % (len(value), data_len))rN   r   )r<   rP   rQ   rR   r   ZPIPE_MAX_SIZErS   r,   r$   rT   r   rW   ÚwriteÚ
memoryviewrU   r7   )r   rX   rY   r[   r/   r   Úwrittenr   r   r   Ú
test_write   s>    
í

zOSEINTRTest.test_writeN)r(   r)   r*   r+   r0   r;   r=   ÚunittestÚ
skipUnlessÚhasattrr<   r@   rB   rF   rH   r\   rc   r   r   r   r   r.   N   s   	

r.   c                   @   sô   e Zd ZdZe eedƒd¡dd„ ƒZdd„ Z	e eejdƒd	¡d
d„ ƒZ
dd„ Zdd„ Zdd„ Ze eejdƒd¡dd„ ƒZdd„ Ze dd¡e eedƒd¡dd„ ƒƒZdd„ Ze ejd kd!¡d"d#„ ƒZd$d%„ Ze ejd kd!¡d&d'„ ƒZd(S ))ÚSocketEINTRTestz$ EINTR tests for the socket module. Ú
socketpairzneeds socketpair()c           	      C   sê   t  ¡ \}}|  |j¡ g d¢}d ddddt|jƒ dt|jƒ d| d	| j dd
dddddddf¡}| 	¡ }| j
|t|ƒ|gd}t|ƒH | ¡  |D ]}|  |||t|ƒƒ¡ qœ|  | ¡ d¡ W d   ƒ n1 sÜ0    Y  d S )N)r]   ó   yó   zrI   úimport os, socket, sys, timerJ   úfd = int(sys.argv[1])úfamily = %súsock_type = %srK   rL   z)wr = socket.fromfd(fd, family, sock_type)úos.close(fd)zwith wr:z    for data in datas:z(        # let the parent block on recv()z        time.sleep(sleep_time)z        wr.sendall(data)rN   r   )Úsocketrh   rQ   rR   rS   ÚintÚfamilyÚtyper,   Úfilenor$   rT   r   rU   rW   r7   )	r   Z	recv_funcrX   rY   rZ   r/   Úfdr   r[   r   r   r   Ú
_test_recv»   s8    ð
zSocketEINTRTest._test_recvc                 C   s   |   tjj¡ d S r!   )rv   rp   Úrecvr   r   r   r   Ú	test_recvß   s    zSocketEINTRTest.test_recvÚrecvmsgzneeds recvmsg()c                 C   s   |   dd„ ¡ d S )Nc                 S   s   |   |¡d S r   )ry   ©Úsockr[   r   r   r   r?   ä   r5   z.SocketEINTRTest.test_recvmsg.<locals>.<lambda>)rv   r   r   r   r   Útest_recvmsgâ   s    zSocketEINTRTest.test_recvmsgc           
      C   s(  t  ¡ \}}|  |j¡ dtjd  }d ddddt|jƒ dt|j	ƒ d	| j
 d
tjd  dddddddddddddddddf¡}| ¡ }| j|t|ƒ|gd}t|ƒh | ¡  d}|t|ƒk rô||t|ƒ|d … ƒ}	||	d u rìt|ƒn|	7 }q¸|  | ¡ d¡ W d   ƒ n1 s0    Y  d S )Ns   xyzr1   rI   rk   rJ   rl   rm   rn   rL   zdata = b"xyz" * %sr^   z)rd = socket.fromfd(fd, family, sock_type)ro   zwith rd:z$    # let the parent block on send()rM   z'    received_data = bytearray(data_len)z	    n = 0z    while n < data_len:z8        n += rd.recv_into(memoryview(received_data)[n:])zif received_data != data:z0    raise Exception("recv error: %s vs %s bytes"z5                    % (len(received_data), data_len))rN   r   )rp   rh   rQ   rR   r   ZSOCK_MAX_SIZErS   rq   rr   rs   r,   rt   r$   rT   r   rW   ra   rU   r7   )
r   Z	send_funcrX   rY   r[   r/   ru   r   rb   Úsentr   r   r   Ú
_test_sendæ   sL    è
zSocketEINTRTest._test_sendc                 C   s   |   tjj¡ d S r!   )r~   rp   Úsendr   r   r   r   Ú	test_send  s    zSocketEINTRTest.test_sendc                 C   s   |   tjj¡ d S r!   )r~   rp   Úsendallr   r   r   r   Útest_sendall  s    zSocketEINTRTest.test_sendallÚsendmsgzneeds sendmsg()c                 C   s   |   dd„ ¡ d S )Nc                 S   s   |   |g¡S r!   )rƒ   rz   r   r   r   r?     r5   z.SocketEINTRTest.test_sendmsg.<locals>.<lambda>)r~   r   r   r   r   Útest_sendmsg  s    zSocketEINTRTest.test_sendmsgc                 C   s°   t  tjdf¡}|  |j¡ | ¡ d }d dddtj d| d| j dd	d
ddf
¡}|  	|¡}t
|ƒ4 | ¡ \}}| ¡  |  | ¡ d¡ W d   ƒ n1 s¢0    Y  d S )Nr   r   rI   zimport socket, timerJ   z	host = %rz	port = %srL   z# let parent block on accept()r_   z,with socket.create_connection((host, port)):rM   )rp   Úcreate_serverr   ZHOSTrQ   rR   ÚgetsocknamerS   r,   r$   r   ÚacceptrU   r7   )r   r{   Úportr/   r   Zclient_sockr3   r   r   r   Útest_accept  s(    ö

zSocketEINTRTest.test_accepté
   r1   Úmkfifozneeds mkfifo()c                 C   sÔ   t j}t  |¡ zt |¡ W n2 tyP } z|  d| ¡ W Y d }~n
d }~0 0 |  t j|¡ d ddd| d| j	 dddd|f	¡}|  
|¡}t|ƒ( ||ƒ |  | ¡ d	¡ W d   ƒ n1 sÆ0    Y  d S )
Nzos.mkfifo(): %srI   úimport os, timerJ   z	path = %arL   z# let the parent blockr_   r   )r   ÚTESTFNÚunlinkr<   r‹   ÚPermissionErrorZskipTestrQ   rS   r,   r$   r   rU   r7   )r   Zdo_open_close_readerZdo_open_close_writerÚfilenameÚer/   r   r   r   r   Ú
_test_open:  s,    
$÷

zSocketEINTRTest._test_openc                 C   s   t |dƒ}| ¡  d S )NÚw)ÚopenrR   )r   ÚpathÚfpr   r   r   Úpython_openY  s    
zSocketEINTRTest.python_openÚdarwinz+hangs under macOS; see bpo-25234, bpo-35363c                 C   s   |   d| j¡ d S )Nzfp = open(path, 'r')
fp.close())r’   r—   r   r   r   r   Ú	test_open]  s    ÿzSocketEINTRTest.test_openc                 C   s   t  |t j¡}t  |¡ d S r!   )r<   r”   ÚO_WRONLYrR   )r   r•   ru   r   r   r   Úos_openc  s    zSocketEINTRTest.os_openc                 C   s   |   d| j¡ d S )Nz,fd = os.open(path, os.O_RDONLY)
os.close(fd))r’   r›   r   r   r   r   Útest_os_openg  s    ÿzSocketEINTRTest.test_os_openN)r(   r)   r*   r+   rd   re   rf   rp   rv   rx   r|   r~   r€   r‚   r„   r‰   r   Zrequires_freebsd_versionr<   r’   r—   ÚskipIfr   Úplatformr™   r›   rœ   r   r   r   r   rg   ·   s2   
#
.

ÿ
ÿrg   c                   @   s   e Zd ZdZdd„ ZdS )ÚTimeEINTRTestz" EINTR tests for the time module. c                 C   s:   t  ¡ }t  | j¡ |  ¡  t  ¡ | }|  || j¡ d S r!   )ÚtimeÚ	monotonicÚsleepr,   r    ÚassertGreaterEqual©r   Út0Údtr   r   r   Ú
test_sleepr  s
    zTimeEINTRTest.test_sleepN)r(   r)   r*   r+   r§   r   r   r   r   rŸ   n  s   rŸ   Úpthread_sigmaskzneed signal.pthread_sigmask()c                   @   sL   e Zd ZdZdd„ Ze eedƒd¡dd„ ƒZ	e eedƒd¡d	d
„ ƒZ
dS )ÚSignalEINTRTestz$ EINTR tests for the signal module. c           
      C   sà   t j}t ¡ }t   |dd„ ¡}|  t j ||¡ d ddt ¡  dt|ƒ d| j dd	f¡}t  t j	|g¡}|  t jt j
|g¡ t ¡ }|  |¡}t|ƒ$ ||ƒ t ¡ | }	W d   ƒ n1 sÂ0    Y  |  | ¡ d
¡ d S )Nc                  W   s   d S r!   r   )r&   r   r   r   r?   †  r5   z/SignalEINTRTest.check_sigwait.<locals>.<lambda>rI   rŒ   zpid = %szsignum = %srL   r_   zos.kill(pid, signum)r   )r   ÚSIGUSR1r<   ÚgetpidrQ   rS   rq   r,   r¨   Ú	SIG_BLOCKÚSIG_UNBLOCKr    r¡   r$   r   rU   r7   )
r   r8   r   rA   Zold_handlerr/   Zold_maskr¥   r   r¦   r   r   r   Úcheck_sigwait‚  s(    

ú	

*zSignalEINTRTest.check_sigwaitÚsigwaitinfozneed signal.sigwaitinfo()c                 C   s   dd„ }|   |¡ d S )Nc                 S   s   t  | g¡ d S r!   )r   r¯   ©r   r   r   r   r8      s    z3SignalEINTRTest.test_sigwaitinfo.<locals>.wait_func©r®   ©r   r8   r   r   r   Útest_sigwaitinfo  s    z SignalEINTRTest.test_sigwaitinfoÚsigtimedwaitc                 C   s   dd„ }|   |¡ d S )Nc                 S   s   t  | gd¡ d S )Ng      ^@)r   r´   r°   r   r   r   r8   ¨  s    z4SignalEINTRTest.test_sigtimedwait.<locals>.wait_funcr±   r²   r   r   r   Útest_sigtimedwait¥  s    z!SignalEINTRTest.test_sigtimedwaitN)r(   r)   r*   r+   r®   rd   re   rf   r   r³   rµ   r   r   r   r   r©   z  s   ÿ
ÿr©   c                   @   s’   e Zd ZdZdd„ Ze ejdkd¡e 	e
edƒd¡dd	„ ƒƒZe 	e
ed
ƒd¡dd„ ƒZe 	e
edƒd¡dd„ ƒZe 	e
edƒd¡dd„ ƒZdS )ÚSelectEINTRTestz$ EINTR tests for the select module. c                 C   s@   t  ¡ }t g g g | j¡ t  ¡ | }|  ¡  |  || j¡ d S r!   )r    r¡   Úselectr,   r    r£   r¤   r   r   r   Útest_select²  s
    zSelectEINTRTest.test_selectr˜   z(poll may fail on macOS; see issue #28087Úpollzneed select.pollc                 C   sF   t  ¡ }t ¡ }| | jd ¡ t ¡ | }|  ¡  |  || j¡ d S ©Ng     @@)r·   r¹   r    r¡   r,   r    r£   ©r   Zpollerr¥   r¦   r   r   r   Ú	test_poll¹  s    zSelectEINTRTest.test_pollÚepollzneed select.epollc                 C   sN   t  ¡ }|  |j¡ t ¡ }| | j¡ t ¡ | }|  ¡  |  	|| j¡ d S r!   )
r·   r½   rQ   rR   r    r¡   r¹   r,   r    r£   r»   r   r   r   Ú
test_epollÅ  s    zSelectEINTRTest.test_epollÚkqueuezneed select.kqueuec                 C   sR   t  ¡ }|  |j¡ t ¡ }| d d| j¡ t ¡ | }|  ¡  |  	|| j¡ d S r   )
r·   r¿   rQ   rR   r    r¡   Zcontrolr,   r    r£   )r   r¿   r¥   r¦   r   r   r   Útest_kqueueÐ  s    zSelectEINTRTest.test_kqueueÚdevpollzneed select.devpollc                 C   sR   t  ¡ }|  |j¡ t ¡ }| | jd ¡ t ¡ | }|  ¡  |  	|| j¡ d S rº   )
r·   rÁ   rQ   rR   r    r¡   r¹   r,   r    r£   r»   r   r   r   Útest_devpollÛ  s    zSelectEINTRTest.test_devpollN)r(   r)   r*   r+   r¸   rd   r   r   rž   re   rf   r·   r¼   r¾   rÀ   rÂ   r   r   r   r   r¶   ®  s   ÿ	



r¶   c                   @   s8   e Zd Zdd„ Ze e ¡ dkd¡dd„ ƒZdd„ Z	d	S )
ÚFNTLEINTRTestc              
   C   s<  |   tjtj¡ d ddtj d| d| j f¡}t ¡ }|  |¡}t	|ƒÚ t
tjdƒ¤}t ¡ | }|dkr|td| ƒ‚z,||tjtjB ƒ ||tjƒ t d	¡ W q\ ty¾   Y qÂY q\0 q\||tjƒ t ¡ | }|  || j¡ |  ¡  W d   ƒ n1 s0    Y  | ¡  W d   ƒ n1 s.0    Y  d S )
NrI   zimport fcntl, timezwith open('%s', 'wb') as f:z   fcntl.%s(f, fcntl.LOCK_EX)z   time.sleep(%s)Úwbg      N@z failed to sync child in %.1f secg{®Gáz„?)rQ   r   rŽ   r   rS   r,   r    r¡   r$   r   r”   Ú	ExceptionÚfcntlZLOCK_EXZLOCK_NBZLOCK_UNr¢   ÚBlockingIOErrorr£   r    r7   )r   Z	lock_funcZ	lock_namer/   Z
start_timer   Úfr¦   r   r   r   Ú_lockè  s2    ü

(zFNTLEINTRTest._lockZAIXzAIX returns PermissionErrorc                 C   s   |   tjd¡ d S )NÚlockf)rÉ   rÆ   rÊ   r   r   r   r   Ú
test_lockf  s    zFNTLEINTRTest.test_lockfc                 C   s   |   tjd¡ d S )NÚflock)rÉ   rÆ   rÌ   r   r   r   r   Ú
test_flock  s    zFNTLEINTRTest.test_flockN)
r(   r)   r*   rÉ   rd   r   rž   ÚsystemrË   rÍ   r   r   r   r   rÃ   ç  s    
rÃ   Ú__main__)r+   Ú
contextlibr   rÆ   r<   rž   r·   r   rp   r$   r   r    rd   Útestr   Ztest.supportr   Úcontextmanagerr   re   rf   ZTestCaser
   r.   rg   rŸ   r©   r¶   rÃ   r(   Úmainr   r   r   r   Ú<module>   sF   


'h 7ÿ/8)
