o
    GXîhF  ã                   @   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 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 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)Ú	os_helper)Úsocket_helperc                 c   sH    |  z| V  W n   |   ¡  ‚ W d  ƒ dS 1 sw   Y  dS )zGContext manager killing the subprocess if a Python exception is raised.N)Úkill)Úproc© r   ú:/opt/python-3.10.19/usr/lib/python3.10/test/_test_eintr.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   Ú
sighandler3   ó   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   ÚsetUp6   s   ÿ
ÿzEINTRBaseTest.setUpc                   C   s   t  t jdd¡ d S ©Nr   )r   r
   r   r   r   r   r   Ú
stop_alarmA   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   ÚtearDownE   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&   J   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_processS   s   

zOSEINTRTest.new_sleep_processc                    sD   d}‡ fdd„t |ƒD ƒ}t |ƒD ]}|ƒ  q|D ]}| ¡  qd S )Né   c                    s   g | ]}ˆ   ¡ ‘qS r   )r2   )Ú.0Ú_r   r   r   Ú
<listcomp>Y   s    z3OSEINTRTest._test_wait_multiple.<locals>.<listcomp>)ÚrangeÚwait)r   Ú	wait_funcÚnumÚ	processesr5   r   r   r   r   Ú_test_wait_multipleW   s   
ÿzOSEINTRTest._test_wait_multiplec                 C   s   |   tj¡ d S r#   )r<   Úosr8   r   r   r   r   Ú	test_wait`   ó   zOSEINTRTest.test_waitÚwait3zrequires wait3()c                 C   ó   |   dd„ ¡ d S )Nc                   S   s
   t  d¡S r!   )r=   r@   r   r   r   r   Ú<lambda>e   s   
 z(OSEINTRTest.test_wait3.<locals>.<lambda>)r<   r   r   r   r   Ú
test_wait3c   ó   zOSEINTRTest.test_wait3c                 C   s   |   ¡ }||jƒ | ¡  d S r#   )r2   Úpidr8   )r   r9   r   r   r   r   Ú_test_wait_singleg   s   
zOSEINTRTest._test_wait_singlec                 C   rA   )Nc                 S   ó   t  | d¡S r!   )r=   Úwaitpid©rE   r   r   r   rB   n   ó    z*OSEINTRTest.test_waitpid.<locals>.<lambda>©rF   r   r   r   r   Útest_waitpidm   r   zOSEINTRTest.test_waitpidÚwait4zrequires wait4()c                 C   rA   )Nc                 S   rG   r!   )r=   rM   rI   r   r   r   rB   r   rJ   z(OSEINTRTest.test_wait4.<locals>.<lambda>rK   r   r   r   r   Ú
test_wait4p   rD   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|ƒ' t  |¡ |D ]}|  	|t  
|t|ƒ¡¡ q<|  	| ¡ d¡ W d   ƒ d S 1 s^w   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Úlenr8   )r   ÚrdÚwrÚdatasr1   r   Údatar   r   r   Ú	test_readt   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
|ƒ2 t  |¡ d}|t|ƒk ra|t  |t|ƒ|d … ¡7 }|t|ƒk sM|  | ¡ d¡ W d   ƒ d S 1 stw   Y  d S )Nó   xrO   zimport io, os, sys, timerP   zrd = int(sys.argv[1])rR   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))rT   r   )r=   rV   rW   rX   r   ZPIPE_MAX_SIZErY   r.   r&   rZ   r	   r]   ÚwriteÚ
memoryviewr[   r8   )r   r^   r_   ra   r1   r   Úwrittenr   r   r   Ú
test_write‘   sB   
í

ÿ"ûzOSEINTRTest.test_writeN)r*   r+   r,   r-   r2   r<   r>   ÚunittestÚ
skipUnlessÚhasattrr=   rC   rF   rL   rN   rb   ri   r   r   r   r   r0   O   s    	

r0   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|ƒ% | ¡  |D ]}|  |||t|ƒƒ¡ qN|  | ¡ d¡ W d   ƒ d S 1 sow   Y  d S )N)rc   ó   yó   zrO   úimport os, socket, sys, timerP   úfd = int(sys.argv[1])úfamily = %súsock_type = %srQ   rR   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)rT   r   )Úsocketrn   rW   rX   rY   ÚintÚfamilyÚtyper.   Úfilenor&   rZ   r	   r[   r]   r8   )	r   Z	recv_funcr^   r_   r`   r1   Úfdr   ra   r   r   r   Ú
_test_recv¼   s:   ð
"üzSocketEINTRTest._test_recvc                 C   ó   |   tjj¡ d S r#   )r|   rv   Úrecvr   r   r   r   Ú	test_recvà   r   zSocketEINTRTest.test_recvÚrecvmsgzneeds recvmsg()c                 C   rA   )Nc                 S   s   |   |¡d S r!   )r€   ©Úsockra   r   r   r   rB   å   s    z.SocketEINTRTest.test_recvmsg.<locals>.<lambda>)r|   r   r   r   r   Útest_recvmsgã   rD   zSocketEINTRTest.test_recvmsgc           
      C   s2  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|ƒ: | ¡  d}|t|ƒk r||t|ƒ|d … ƒ}	||	d u rvt|ƒn|	7 }|t|ƒk sb|  | ¡ d¡ W d   ƒ d S 1 s’w   Y  d S )Ns   xyzr3   rO   rq   rP   rr   rs   rt   rR   zdata = b"xyz" * %srd   z)rd = socket.fromfd(fd, family, sock_type)ru   zwith rd:z$    # let the parent block on send()rS   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))rT   r   )rv   rn   rW   rX   r   ZSOCK_MAX_SIZErY   rw   rx   ry   r.   rz   r&   rZ   r	   r]   rg   r[   r8   )
r   Z	send_funcr^   r_   ra   r1   r{   r   rh   Úsentr   r   r   Ú
_test_sendç   sP   è
ý"ùzSocketEINTRTest._test_sendc                 C   r}   r#   )r…   rv   Úsendr   r   r   r   Ú	test_send  r   zSocketEINTRTest.test_sendc                 C   r}   r#   )r…   rv   Úsendallr   r   r   r   Útest_sendall  r   zSocketEINTRTest.test_sendallÚsendmsgzneeds sendmsg()c                 C   rA   )Nc                 S   s   |   |g¡S r#   )rŠ   r   r   r   r   rB     rJ   z.SocketEINTRTest.test_sendmsg.<locals>.<lambda>)r…   r   r   r   r   Útest_sendmsg  rD   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
|ƒ | ¡ \}}| ¡  |  | ¡ d¡ W d   ƒ d S 1 sRw   Y  d S )Nr   r   rO   zimport socket, timerP   z	host = %rz	port = %srR   z# let parent block on accept()re   z,with socket.create_connection((host, port)):rS   )rv   Úcreate_serverr   ZHOSTrW   rX   ÚgetsocknamerY   r.   r&   r	   Úacceptr[   r8   )r   r‚   Úportr1   r   Zclient_sockr5   r   r   r   Útest_accept  s*   ö

"ýzSocketEINTRTest.test_accepté
   r3   Úmkfifozneeds mkfifo()c                 C   sÖ   t j}t  |¡ zt |¡ W n ty( } z|  d| ¡ W Y d }~nd }~ww |  t j|¡ d ddd| d| j	 dddd|f	¡}|  
|¡}t|ƒ ||ƒ |  | ¡ d	¡ W d   ƒ d S 1 sdw   Y  d S )
Nzos.mkfifo(): %srO   úimport os, timerP   z	path = %arR   z# let the parent blockre   r   )r   ÚTESTFNÚunlinkr=   r’   ÚPermissionErrorZskipTestrW   rY   r.   r&   r	   r[   r8   )r   Zdo_open_close_readerZdo_open_close_writerÚfilenameÚer1   r   r   r   r   Ú
_test_open;  s2   
€ÿ÷

"þzSocketEINTRTest._test_openc                 C   s   t |dƒ}| ¡  d S )NÚw)ÚopenrX   )r   ÚpathÚfpr   r   r   Úpython_openZ  s   
zSocketEINTRTest.python_openÚdarwinz+hangs under macOS; see bpo-25234, bpo-35363c                 C   ó   |   d| j¡ d S )Nzfp = open(path, 'r')
fp.close())r™   rž   r   r   r   r   Ú	test_open^  ó   ÿzSocketEINTRTest.test_openc                 C   s   t  |t j¡}t  |¡ d S r#   )r=   r›   ÚO_WRONLYrX   )r   rœ   r{   r   r   r   Úos_opend  s   zSocketEINTRTest.os_openc                 C   r    )Nz,fd = os.open(path, os.O_RDONLY)
os.close(fd))r™   r¤   r   r   r   r   Útest_os_openh  r¢   zSocketEINTRTest.test_os_openN)r*   r+   r,   r-   rj   rk   rl   rv   r|   r   rƒ   r…   r‡   r‰   r‹   r   r   Zrequires_freebsd_versionr=   r™   rž   ÚskipIfr   Úplatformr¡   r¤   r¥   r   r   r   r   rm   ¸   s4    
#
.

ÿ
ÿrm   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_sleeps  s
   zTimeEINTRTest.test_sleepN)r*   r+   r,   r-   r°   r   r   r   r   r¨   o  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 saw   Y  |  | ¡ d
¡ d S )Nc                  W   s   d S r#   r   )r(   r   r   r   rB   ‡  s    z/SignalEINTRTest.check_sigwait.<locals>.<lambda>rO   r“   zpid = %szsignum = %srR   re   zos.kill(pid, signum)r   )r   ÚSIGUSR1r=   ÚgetpidrW   rY   rw   r.   r±   Ú	SIG_BLOCKÚSIG_UNBLOCKr©   rª   r&   r	   r[   r8   )
r   r9   r   rE   Zold_handlerr1   Zold_maskr®   r   r¯   r   r   r   Úcheck_sigwaitƒ  s*   

ú	

þzSignalEINTRTest.check_sigwaitÚsigwaitinfozneed signal.sigwaitinfo()c                 C   ó   dd„ }|   |¡ d S )Nc                 S   s   t  | g¡ d S r#   )r   r¸   ©r   r   r   r   r9   ¡  r?   z3SignalEINTRTest.test_sigwaitinfo.<locals>.wait_func©r·   ©r   r9   r   r   r   Útest_sigwaitinfož  ó   z SignalEINTRTest.test_sigwaitinfoÚsigtimedwaitc                 C   r¹   )Nc                 S   s   t  | gd¡ d S )Ng      ^@)r   r¿   rº   r   r   r   r9   ©  r   z4SignalEINTRTest.test_sigtimedwait.<locals>.wait_funcr»   r¼   r   r   r   Útest_sigtimedwait¦  r¾   z!SignalEINTRTest.test_sigtimedwaitN)r*   r+   r,   r-   r·   rj   rk   rl   r   r½   rÀ   r   r   r   r   r²   {  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È   rW   rX   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Ê   rW   rX   r©   rª   Zcontrolr.   r"   r¬   )r   rÊ   r®   r¯   r   r   r   Útest_kqueueÑ  ó   zSelectEINTRTest.test_kqueueÚdevpollzneed select.devpollc                 C   sR   t  ¡ }|  |j¡ t ¡ }| | jd ¡ t ¡ | }|  ¡  |  	|| j¡ d S rÅ   )
rÂ   rÍ   rW   rX   r©   rª   rÄ   r.   r"   r¬   rÆ   r   r   r   Útest_devpollÜ  rÌ   zSelectEINTRTest.test_devpollN)r*   r+   r,   r-   rÃ   rj   r¦   r   r§   rk   rl   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   s8  |   tjtj¡ d ddtj d| d| j f¡}t ¡ }|  |¡}t	|ƒl t
tjdƒQ}	 t ¡ | }|dkr?td	| ƒ‚z||tjtjB ƒ ||tjƒ t d
¡ W n	 ty^   Y nw q/||tjƒ t ¡ | }|  || j¡ |  ¡  W d   ƒ n1 sw   Y  | ¡  W d   ƒ d S 1 s•w   Y  d S )NrO   zimport fcntl, timezwith open('%s', 'wb') as f:z   fcntl.%s(f, fcntl.LOCK_EX)z   time.sleep(%s)ÚwbTg      N@z failed to sync child in %.1f secg{®Gáz„?)rW   r   r•   r”   rY   r.   r©   rª   r&   r	   r›   Ú	ExceptionÚfcntlÚLOCK_EXÚLOCK_NBÚLOCK_UNr«   ÚBlockingIOErrorr¬   r"   r8   )r   Z	lock_funcZ	lock_namer1   Z
start_timer   Úfr¯   r   r   r   Ú_locké  s<   ü

ÿø
ï
"ízFNTLEINTRTest._lockZAIXzAIX returns PermissionErrorc                 C   ó   |   tjd¡ d S )NÚlockf)rØ   rÒ   rÚ   r   r   r   r   Ú
test_lockf	  rD   zFNTLEINTRTest.test_lockfc                 C   rÙ   )NÚflock)rØ   rÒ   rÜ   r   r   r   r   Ú
test_flock  r   zFNTLEINTRTest.test_flockN)
r*   r+   r,   rØ   rj   r¦   r§   ÚsystemrÛ   rÝ   r   r   r   r   rÏ   è  s
     
rÏ   Ú__main__) r-   Ú
contextlibr   rÒ   r=   r§   rÂ   r   rv   r&   r   r©   rj   Útestr   Ztest.supportr   r   Úcontextmanagerr	   rk   rl   ZTestCaser   r0   rm   r¨   r²   rÁ   rÏ   r*   Úmainr   r   r   r   Ú<module>   sL    


'h 7ÿ/8)ÿ