
    ;eF                     x   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             Z ej         eed          d           G d	 d
ej                              Z ej         eed          d           G d de                      Z ej         eed          d           G d de                      Z ej         eed          d           G d de                      Z ej         eed          d           ej         eed          d           G d de                                  Z ej         eed          d           G d de                      Z G d de          Zedk    r ej                     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              #      K   | 5  	 | V  n#  |                                    xY w	 ddd           dS # 1 swxY w Y   dS )zGContext manager killing the subprocess if a Python exception is raised.N)kill)procs    '/usr/lib/python3.11/test/_test_eintr.pykill_on_errorr
      s       
  	JJJJ	IIKKK                  s   44#488	setitimerzrequires setitimer()c                   L    e Zd ZdZdZdZdZd Zd Ze	d             Z
d Zd Zd	S )
EINTRBaseTestz Base class for EINTR tests. g?g?c                 &    | xj         dz  c_         d S N   )signals)selfsignumframes      r	   
sighandlerzEINTRBaseTest.sighandler3   s        c                     d| _         t          j        t          j        | j                  | _        t          j        t          j        | j        | j                   t          j
        ddt          j                   d S )Nr   iX  T)exitfile)r   signalSIGALRMr   orig_handlerr   ITIMER_REALsignal_delaysignal_periodfaulthandlerdump_traceback_latersys
__stderr__r   s    r	   setUpzEINTRBaseTest.setUp6   su    "M&.$/JJ+T->+	- 	- 	-
 	)'/2~	? 	? 	? 	? 	? 	?r   c                  F    t          j        t           j        dd           d S Nr   )r   r   r    r   r	   
stop_alarmzEINTRBaseTest.stop_alarmA   s     +Q22222r   c                     |                                   t          j        t          j        | j                   t	          j                     d S N)r)   r   r   r   r    cancel_dump_traceback_laterr$   s    r	   tearDownzEINTRBaseTest.tearDownE   s>    fnd&7888022222r   c                 H    t           j        df|z   }t          j        |fi |S )Nz-c)r"   
executable
subprocessPopen)r   argskwcmd_argss       r	   r0   zEINTRBaseTest.subprocessJ   s,    ND)D0//B///r   N)__name__
__module____qualname____doc__r   r   
sleep_timer   r%   staticmethodr)   r-   r0   r(   r   r	   r   r   '   s        '' LM J  	? 	? 	? 3 3 \33 3 3
0 0 0 0 0r   r   c                       e Zd ZdZd Zd Zd Z ej         e	e
d          d          d             Zd Zd	 Z ej         e	e
d
          d          d             Zd Zd ZdS )OSEINTRTestz  EINTR tests for the os module. c                 @    d| j         z  }|                     |          S )Nzimport time; time.sleep(%r))r9   r0   )r   codes     r	   new_sleep_processzOSEINTRTest.new_sleep_processS   s     ,t>t$$$r   c                      d} fdt          |          D             }t          |          D ]} |             |D ]}|                                 d S )N   c                 8    g | ]}                                 S r(   )r?   ).0_r   s     r	   
<listcomp>z3OSEINTRTest._test_wait_multiple.<locals>.<listcomp>Y   s%    BBB!T++--BBBr   )rangewait)r   	wait_funcnum	processesrD   r   s   `     r	   _test_wait_multiplezOSEINTRTest._test_wait_multipleW   sq    BBBBuSzzBBB	s 	 	AIKKKK 	 	DIIKKKK	 	r   c                 D    |                      t          j                   d S r+   )rK   osrG   r$   s    r	   	test_waitzOSEINTRTest.test_wait`   s      )))))r   wait3zrequires wait3()c                 2    |                      d            d S )Nc                  *    t          j        d          S r'   )rM   rO   r(   r   r	   <lambda>z(OSEINTRTest.test_wait3.<locals>.<lambda>e   s    ! r   )rK   r$   s    r	   
test_wait3zOSEINTRTest.test_wait3c   s       !4!455555r   c                 v    |                                  } ||j                   |                                 d S r+   )r?   pidrG   )r   rH   r   s      r	   _test_wait_singlezOSEINTRTest._test_wait_singleg   s6    %%''	$(		r   c                 2    |                      d            d S )Nc                 ,    t          j        | d          S r'   )rM   waitpidrU   s    r	   rR   z*OSEINTRTest.test_waitpid.<locals>.<lambda>n   s    2:c1+=+= r   rV   r$   s    r	   test_waitpidzOSEINTRTest.test_waitpidm   s     ==>>>>>r   wait4zrequires wait4()c                 2    |                      d            d S )Nc                 ,    t          j        | d          S r'   )rM   r]   rZ   s    r	   rR   z(OSEINTRTest.test_wait4.<locals>.<lambda>r   s    28C+;+; r   r[   r$   s    r	   
test_wait4zOSEINTRTest.test_wait4p   s     ;;<<<<<r   c                 X   t          j                    \  }}|                     t           j        |           g d}d                    dddd|z  d| j        z  ddd	d
df
          }|                     |t          |          |g          }t          |          5  t          j        |           |D ]8}| 	                    |t          j
        |t          |                               9| 	                    |                                d           d d d            d S # 1 swxY 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   )rM   pipe
addCleanupclosejoinr9   r0   strr
   assertEqualreadlenrG   )r   rdwrdatasr>   r   datas          r	   	test_readzOSEINTRTest.test_readt   sn   B"%%%
 .--yy"#5 / 2($
   tSWWt<<4   	- 	-HRLLL ? ?  rwr3t99'='=>>>>TYY[[!,,,		- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	-s   A8DD#&D#c                    t          j                    \  }}|                     t           j        |           dt          j        z  }d                    dddd| j        z  dt          j        z  ddd	d
ddddddddddf          }|                     |t          |          |g          }t          |          5  t          j        |           d}|t          |          k     r@|t          j        |t          |          |d                    z  }|t          |          k     @|                     |                                d           d d d            d S # 1 swxY w Y   d S )N   xrb   zimport io, os, sys, timerc   zrd = int(sys.argv[1])re   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))rg   r   )rM   ri   rj   rk   r   PIPE_MAX_SIZErl   r9   r0   rm   r
   rp   write
memoryviewrn   rG   )r   rq   rr   rt   r>   r   writtens          r	   
test_writezOSEINTRTest.test_write   s   B"%%% g++yy&#/!66"/$&93(*>;'
  , tSWWt<<4   	- 	-HRLLLGCII%%28B
4(8(8(BCCC CII%%TYY[[!,,,	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	-s   8BEEEN)r5   r6   r7   r8   r?   rK   rN   unittest
skipUnlesshasattrrM   rS   rV   r\   r`   ru   r~   r(   r   r	   r<   r<   O   s        **% % %  * * * XW--/ABB6 6 CB6  ? ? ? XW--/ABB= = CB=- - -:$- $- $- $- $-r   r<   c                   *   e Zd ZdZ ej         eed          d          d             Zd Z	 ej         eej        d          d          d             Z
d	 Zd
 Zd Z ej         eej        d          d          d             Zd Z ej        dd           ej         eed          d          d                         Zd Z ej        ej        dk    d          d             Zd Z ej        ej        dk    d          d             ZdS )SocketEINTRTestz$ EINTR tests for the socket module. 
socketpairzneeds socketpair()c                    t          j                    \  }}|                     |j                   g d}d                    ddddt          |j                  z  dt          |j                  z  d|z  d	| j        z  dd
dddddddf          }|	                                }| 
                    |t          |          |g          }t          |          5  |                                 |D ]/}|                     | ||t          |                               0|                     |                                d           d d d            d S # 1 swxY w Y   d S )N)rw      y   zrb   import os, socket, sys, timerc   fd = int(sys.argv[1])family = %ssock_type = %srd   re   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)rg   r   )socketr   rj   rk   rl   intfamilytyper9   filenor0   rm   r
   rn   rp   rG   )	r   	recv_funcrq   rr   rs   r>   fdr   rt   s	            r	   
_test_recvzSocketEINTRTest._test_recv   s   "$$B!!! #""yy*#C	NN*s27||+5 /7$6,&!
  & YY[[tSWWt<<4   	- 	-HHJJJ A A  yySYY'?'?@@@@TYY[[!,,,		- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	-s   A/EEEc                 N    |                      t          j        j                   d S r+   )r   r   recvr$   s    r	   	test_recvzSocketEINTRTest.test_recv       *+++++r   recvmsgzneeds recvmsg()c                 2    |                      d            d S )Nc                 8    |                      |          d         S r'   )r   sockrt   s     r	   rR   z.SocketEINTRTest.test_recvmsg.<locals>.<lambda>   s    4<<+=+=a+@ r   )r   r$   s    r	   test_recvmsgzSocketEINTRTest.test_recvmsg   s    @@AAAAAr   c                 b   t          j                    \  }}|                     |j                   dt          j        dz  z  }d                    ddddt          |j                  z  dt          |j	                  z  d	| j
        z  d
t          j        dz  z  dddddddddddddddddf          }|                                }|                     |t          |          |g          }t          |          5  |                                 d}|t          |          k     rJ ||t!          |          |d                    }	||	t          |          n|	z  }|t          |          k     J|                     |                                d           d d d            d S # 1 swxY w Y   d S )Ns   xyzrA   rb   r   rc   r   r   r   re   zdata = b"xyz" * %srx   z)rd = socket.fromfd(fd, family, sock_type)r   zwith rd:z$    # let the parent block on send()rf   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))rg   r   )r   r   rj   rk   r   SOCK_MAX_SIZErl   r   r   r   r9   r   r0   rm   r
   rp   r|   rn   rG   )
r   	send_funcrq   rr   rt   r>   r   r   r}   sents
             r	   
_test_sendzSocketEINTRTest._test_send   s   "$$B!!! .!34yy*#C	NN*s27||+/ G$9Q$>?"72(5%F'>C1
  6 YY[[tSWWt<<4   	- 	-HHJJJGCII%% yZ%5%5ghh%?@@3t999$> CII%% TYY[[!,,,	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	-s   ;BF$$F(+F(c                 N    |                      t          j        j                   d S r+   )r   r   sendr$   s    r	   	test_sendzSocketEINTRTest.test_send  r   r   c                 N    |                      t          j        j                   d S r+   )r   r   sendallr$   s    r	   test_sendallzSocketEINTRTest.test_sendall  s    -.....r   sendmsgzneeds sendmsg()c                 2    |                      d            d S )Nc                 .    |                      |g          S r+   )r   r   s     r	   rR   z.SocketEINTRTest.test_sendmsg.<locals>.<lambda>  s    4<<+?+? r   )r   r$   s    r	   test_sendmsgzSocketEINTRTest.test_sendmsg  s    ??@@@@@r   c                 <   t          j        t          j        df          }|                     |j                   |                                d         }d                    dddt          j        z  d|z  d| j        z  dd	d
ddf
          }| 	                    |          }t          |          5  |                                \  }}|                                 |                     |                                d           d d d            d S # 1 swxY w Y   d S )Nr   r   rb   zimport socket, timerc   z	host = %rz	port = %sre   z# let parent block on accept()ry   z,with socket.create_connection((host, port)):rf   )r   create_serverr   HOSTrj   rk   getsocknamerl   r9   r0   r
   acceptrn   rG   )r   r   portr>   r   client_sockrD   s          r	   test_acceptzSocketEINTRTest.test_accept  sT   #]%7$;<<
###!!!$yy!-,,$/,$:(
   t$$4   	- 	-![[]]NKTYY[[!,,,	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	-s   0ADDD
   rA   mkfifozneeds mkfifo()c                 B   t           j        }t          j        |           	 t          j        |           n/# t
          $ r"}|                     d|z             Y d }~nd }~ww xY w|                     t           j        |           d                    ddd|z  d| j	        z  dddd|f	          }| 
                    |          }t          |          5   ||           |                     |                                d	           d d d            d S # 1 swxY w Y   d S )
Nzos.mkfifo(): %srb   import os, timerc   z	path = %are   z# let the parent blockry   r   )r   TESTFNunlinkrM   r   PermissionErrorskipTestrj   rl   r9   r0   r
   rn   rG   )r   do_open_close_readerdo_open_close_writerfilenameer>   r   s          r	   
_test_openzSocketEINTRTest._test_open;  s    # 	"""	1Ih 	1 	1 	1MM+a/00000000	1	((333yy("/$$ 

 
 
 t$$4   	- 	-  ***TYY[[!,,,	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	-s'   7 
A#AA#4DDDc                 N    t          |d          }|                                 d S )Nw)openrk   )r   pathfps      r	   python_openzSocketEINTRTest.python_openZ  s     $__





r   darwinz+hangs under macOS; see bpo-25234, bpo-35363c                 <    |                      d| j                   d S )Nzfp = open(path, 'r')
fp.close())r   r   r$   s    r	   	test_openzSocketEINTRTest.test_open^  s-     	:(	* 	* 	* 	* 	*r   c                 l    t          j        |t           j                  }t          j        |           d S r+   )rM   r   O_WRONLYrk   )r   r   r   s      r	   os_openzSocketEINTRTest.os_opend  s&    WT2;''
r   c                 <    |                      d| j                   d S )Nz,fd = os.open(path, os.O_RDONLY)
os.close(fd))r   r   r$   s    r	   test_os_openzSocketEINTRTest.test_os_openh  s,     	G	& 	& 	& 	& 	&r   N)r5   r6   r7   r8   r   r   r   r   r   r   r   r   r   r   r   r   r   requires_freebsd_versionrM   r   r   skipIfr"   platformr   r   r   r(   r   r	   r   r      s       ..X668LMM!- !- NM!-F, , , X	::<MNNB B ONB,- ,- ,-\, , ,/ / / X	::<MNNA A ONA- - -8 &W%b!,,XX..0@AA- - BA -,-:   X_S\X-BD D* *D D*   X_S\X-BD D& &D D& & &r   r   c                       e Zd ZdZd ZdS )TimeEINTRTestz" EINTR tests for the time module. c                     t          j                    }t          j        | j                   |                                  t          j                    |z
  }|                     || j                   d S r+   )time	monotonicsleepr9   r)   assertGreaterEqualr   t0dts      r	   
test_sleepzTimeEINTRTest.test_sleeps  sa    ^
4?###^"DO44444r   N)r5   r6   r7   r8   r   r(   r   r	   r   r   o  s)        ,,5 5 5 5 5r   r   pthread_sigmaskzneed signal.pthread_sigmask()c                       e Zd ZdZd Z ej         eed          d          d             Z	 ej         eed          d          d             Z
dS )	SignalEINTRTestz$ EINTR tests for the signal module. c                    t           j        }t          j                    }t          j         |d           }|                     t           j         ||           d                    ddt          j                    z  dt          |          z  d| j        z  ddf          }t          j        t           j	        |g          }|                     t           j        t           j
        |g           t          j                    }|                     |          }t          |          5   ||           t          j                    |z
  }	d d d            n# 1 swxY w Y   |                     |                                d	           d S )
Nc                      d S r+   r(   )r2   s    r	   rR   z/SignalEINTRTest.check_sigwait.<locals>.<lambda>  s    $ r   rb   r   zpid = %szsignum = %sre   ry   zos.kill(pid, signum)r   )r   SIGUSR1rM   getpidrj   rl   r   r9   r   	SIG_BLOCKSIG_UNBLOCKr   r   r0   r
   rn   rG   )
r   rH   r   rU   old_handlerr>   old_maskr   r   r   s
             r	   check_sigwaitzSignalEINTRTest.check_sigwait  s   ikkmF,>,>??v{;;;yy$CKK'/$"
   )&*:VHEE.0BVHMMM^t$$4   	' 	'If!!B&B	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	a(((((s   !"EEEsigwaitinfozneed signal.sigwaitinfo()c                 6    d }|                      |           d S )Nc                 0    t          j        | g           d S r+   )r   r   r   s    r	   rH   z3SignalEINTRTest.test_sigwaitinfo.<locals>.wait_func  s    x(((((r   r   r   rH   s     r	   test_sigwaitinfoz SignalEINTRTest.test_sigwaitinfo  s-    	) 	) 	) 	9%%%%%r   sigtimedwaitc                 6    d }|                      |           d S )Nc                 2    t          j        | gd           d S )Ng      ^@)r   r   r   s    r	   rH   z4SignalEINTRTest.test_sigtimedwait.<locals>.wait_func  s    %00000r   r   r   s     r	   test_sigtimedwaitz!SignalEINTRTest.test_sigtimedwait  s-    	1 	1 	1 	9%%%%%r   N)r5   r6   r7   r8   r   r   r   r   r   r   r   r(   r   r	   r   r   {  s         /.) ) )6 X7746 6& &6 6& X8846 6& &6 6& & &r   r   c                   x   e Zd ZdZd Z ej        ej        dk    d           ej	         e
ed          d          d                         Z ej	         e
ed          d	          d
             Z ej	         e
ed          d          d             Z ej	         e
ed          d          d             ZdS )SelectEINTRTestz$ EINTR tests for the select module. c                     t          j                    }t          j        g g g | j                   t          j                    |z
  }|                                  |                     || j                   d S r+   )r   r   selectr9   r)   r   r   s      r	   test_selectzSelectEINTRTest.test_select  sg    ^b"b$/222^"DO44444r   r   z(poll may fail on macOS; see issue #28087pollzneed select.pollc                    t          j                    }t          j                    }|                    | j        dz             t          j                    |z
  }|                                  |                     || j                   d S Ng     @@)r   r   r   r   r9   r)   r   r   pollerr   r   s       r	   	test_pollzSelectEINTRTest.test_poll  su     ^DOc)***^"DO44444r   epollzneed select.epollc                 D   t          j                    }|                     |j                   t	          j                    }|                    | j                   t	          j                    |z
  }|                                  | 	                    || j                   d S r+   )
r   r  rj   rk   r   r   r   r9   r)   r   r   s       r	   
test_epollzSelectEINTRTest.test_epoll  s    %%%^DO$$$^"DO44444r   kqueuezneed select.kqueuec                 H   t          j                    }|                     |j                   t	          j                    }|                    d d| j                   t	          j                    |z
  }|                                  | 	                    || j                   d S r   )
r   r  rj   rk   r   r   controlr9   r)   r   )r   r  r   r   s       r	   test_kqueuezSelectEINTRTest.test_kqueue  s    %%%^tQ000^"DO44444r   devpollzneed select.devpollc                 J   t          j                    }|                     |j                   t	          j                    }|                    | j        dz             t	          j                    |z
  }|                                  | 	                    || j                   d S r   )
r   r  rj   rk   r   r   r   r9   r)   r   r   s       r	   test_devpollzSelectEINTRTest.test_devpoll  s    !!%%%^DOc)***^"DO44444r   N)r5   r6   r7   r8   r   r   r   r"   r   r   r   r   r   r  r  r
  r(   r   r	   r   r     s8       ..5 5 5 X_S\X-?A AX002DEE5 5 FEA A5 X113FGG5 5 HG5 X224HII5 5 JI5 X335JKK5 5 LK5 5 5r   r   c                   p    e Zd Zd Z ej         ej                    dk    d          d             Zd Z	dS )FNTLEINTRTestc                    |                      t          j        t          j                   d                    ddt          j        z  d|z  d| j        z  f          }t          j                    }|                     |          }t          |          5  t          t          j        d          5 }	 t          j                    |z
  }|dk    rt          d	|z            	  ||t          j        t          j        z              ||t          j                   t          j        d
           n# t"          $ r Y nw xY w ||t          j                   t          j                    |z
  }|                     || j                   |                                  d d d            n# 1 swxY w Y   |                                 d d d            d S # 1 swxY w Y   d S )Nrb   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{Gz?)rj   r   r   r   rl   r9   r   r   r0   r
   r   	ExceptionfcntlLOCK_EXLOCK_NBLOCK_UNr   BlockingIOErrorr   r)   rG   )r   	lock_func	lock_namer>   
start_timer   fr   s           r	   _lockzFNTLEINTRTest._lock  sJ   	()*:;;;yy )I,<<+i7$/1	3 4 4
 ^%%
t$$4   	 	i&-- "	))J6BDyy'(JR(OPPP!	!U]U]%BCCC!	!U]333
4((((*   	 	!U]+++^%%
2''DO<<<!!!#" " " " " " " " " " " " " " "$ IIKKK'	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s\   G.0F%AD-,F%-
D:7F%9D::AF%G%F)	)G,F)	-GGGAIXzAIX returns PermissionErrorc                 F    |                      t          j        d           d S )Nlockf)r  r  r  r$   s    r	   
test_lockfzFNTLEINTRTest.test_lockf	  s    

5;(((((r   c                 F    |                      t          j        d           d S )Nflock)r  r  r  r$   s    r	   
test_flockzFNTLEINTRTest.test_flock  s    

5;(((((r   N)
r5   r6   r7   r  r   r   r   systemr  r   r(   r   r	   r  r    sn          @ X__X_&&%/1NOO) ) PO)) ) ) ) )r   r  __main__) r8   
contextlibr    r  rM   r   r   r   r   r0   r"   r   r   testr   test.supportr   r   contextmanagerr
   r   r   TestCaser   r<   r   r   r   r   r  r5   mainr(   r   r	   <module>r)     sj             				         



         " " " " " " & & & & & &   WWV[113IJJ$0 $0 $0 $0 $0H% $0 $0 KJ$0N WWV[113IJJe- e- e- e- e-- e- e- KJe-P WWV[113IJJs& s& s& s& s&m s& s& KJs&l WWV[113IJJ5 5 5 5 5M 5 5 KJ5 WWV[113IJJ WWV%67746 6,& ,& ,& ,& ,&m ,& ,&6 6 KJ
,&^ WWV[113IJJ55 55 55 55 55m 55 55 KJ55p&) &) &) &) &)M &) &) &)R zHMOOOOO r   