f ž _Fã@sœdZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl mZddlmZddlmZejdd„ƒZe  eedƒd ¡Gd d „d e jƒƒZe  eedƒd ¡Gd d „d eƒƒZe  eedƒd ¡Gdd„deƒƒZe  eedƒd ¡Gdd„deƒƒZe  eedƒd ¡e  eedƒd¡Gdd„deƒƒƒZe  eedƒd ¡Gdd„deƒƒZGdd„deƒZedkr˜e  ¡dS)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_helperccsJ|2z |VWn| ¡‚Yn0Wdƒn1s<0YdS)zGContext manager killing the subprocess if a Python exception is raised.N)Úkill)Úproc©rú4/usr/lib64/python3.10/test/eintrdata/eintr_tester.pyÚ kill_on_errors  r Ú setitimerzrequires setitimer()c@sHeZdZdZdZdZdZdd„Zdd„Ze dd „ƒZ d d „Z d d „Z dS)Ú EINTRBaseTestz Base class for EINTR tests. gš™™™™™¹?gš™™™™™É?cCs|jd7_dS©Né)Úsignals)ÚselfÚsignumÚframerrrÚ sighandler3szEINTRBaseTest.sighandlercCsBd|_t tj|j¡|_t tj|j|j¡t j ddt j ddS)NriXT)ÚexitÚfile) rÚsignalÚSIGALRMrÚ orig_handlerr Ú ITIMER_REALÚ signal_delayÚ signal_periodÚ faulthandlerZdump_traceback_laterÚsysÚ __stderr__©rrrrÚsetUp6s ÿÿzEINTRBaseTest.setUpcCst tjdd¡dS©Nr)rr rrrrrÚ stop_alarmAszEINTRBaseTest.stop_alarmcCs$| ¡t tj|j¡t ¡dS©N)r!rrrrZcancel_dump_traceback_laterrrrrÚtearDownEszEINTRBaseTest.tearDowncOs tjdf|}tj|fi|¤ŽS)Nz-c)rÚ executableÚ subprocessÚPopen)rÚargsÚkwZcmd_argsrrrr%JszEINTRBaseTest.subprocessN) Ú__name__Ú __module__Ú __qualname__Ú__doc__rrÚ sleep_timerrÚ staticmethodr!r#r%rrrrr 's  r c@s|eZdZdZdd„Zdd„Zdd„Ze e e dƒd ¡d d „ƒZ d d „Z dd„Z e e e dƒd¡dd„ƒZdd„Zdd„ZdS)Ú OSEINTRTestz EINTR tests for the os module. cCsd|j}| |¡S)Nzimport time; time.sleep(%r))r-r%)rÚcoderrrÚnew_sleep_processSs zOSEINTRTest.new_sleep_processcsDd}‡fdd„t|ƒDƒ}t|ƒD] }|ƒq"|D] }| ¡q2dS)Nécsg|] }ˆ ¡‘qSr)r1)Ú.0Ú_rrrÚ Yóz3OSEINTRTest._test_wait_multiple..)ÚrangeÚwait)rÚ wait_funcÚnumÚ processesr4rrrrÚ_test_wait_multipleWs  zOSEINTRTest._test_wait_multiplecCs| tj¡dSr")r<Úosr8rrrrÚ test_wait`szOSEINTRTest.test_waitÚwait3zrequires wait3()cCs| dd„¡dS)NcSs t d¡Sr )r=r?rrrrÚer6z(OSEINTRTest.test_wait3..)r<rrrrÚ test_wait3cszOSEINTRTest.test_wait3cCs| ¡}||jƒ| ¡dSr")r1Úpidr8)rr9rrrrÚ_test_wait_singlegs zOSEINTRTest._test_wait_singlecCs| dd„¡dS)NcSs t |d¡Sr )r=Úwaitpid©rBrrrr@nr6z*OSEINTRTest.test_waitpid..©rCrrrrÚ test_waitpidmszOSEINTRTest.test_waitpidÚwait4zrequires wait4()cCs| dd„¡dS)NcSs t |d¡Sr )r=rHrErrrr@rr6z(OSEINTRTest.test_wait4..rFrrrrÚ test_wait4pszOSEINTRTest.test_wait4c CsÈt ¡\}}| tj|¡gd¢}d dddd|d|jddd d d f ¡}|j|t|ƒ|gd }t|ƒLt |¡|D]}|  |t  |t |ƒ¡¡qx|  |  ¡d ¡Wdƒn1sº0YdS)N)shellosworldsspamÚ zimport os, sys, timeÚzwr = int(sys.argv[1])ú datas = %rúsleep_time = %rzfor 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Údatasr0rÚdatarrrÚ test_readts* ö   zOSEINTRTest.test_readcCsêt ¡\}}| tj|¡dtj}d dddd|jdtjddd d dd d d ddddddf¡}|j|t |ƒ|gd}t |ƒXt |¡d}|t |ƒkr¸|t  |t |ƒ|d…¡7}qŽ| | ¡d¡Wdƒn1sÜ0YdS)NóxrJzimport io, os, sys, timerKzrd = int(sys.argv[1])rMzdata = b"x" * %súdata_len = len(data)z!# let the parent block on write()útime.sleep(sleep_time)zread_data = io.BytesIO()z+while len(read_data.getvalue()) < data_len:z% chunk = os.read(rd, 2 * data_len)z read_data.write(chunk)zvalue = read_data.getvalue()zif value != data:z0 raise Exception("read error: %s vs %s bytes"z- % (len(value), data_len))rOr)r=rQrRrSrZ PIPE_MAX_SIZErTr-r%rUr rXÚwriteÚ memoryviewrVr8)rrYrZr\r0rÚwrittenrrrÚ test_write‘s>  í   zOSEINTRTest.test_writeN)r)r*r+r,r1r<r>ÚunittestÚ skipUnlessÚhasattrr=rArCrGrIr]rdrrrrr/Os   r/c@sôeZdZdZe eedƒd¡dd„ƒZdd„Z e eejdƒd ¡d d „ƒZ d d „Z dd„Z dd„Z e eejdƒd¡dd„ƒZdd„Ze dd¡e eedƒd¡dd„ƒƒZdd„Ze ejd kd!¡d"d#„ƒZd$d%„Ze ejd kd!¡d&d'„ƒZd(S))ÚSocketEINTRTestz$ EINTR tests for the socket module. Ú socketpairzneeds socketpair()c Csêt ¡\}}| |j¡gd¢}d ddddt|jƒdt|jƒd|d |jdd d dd d dddf¡}|  ¡}|j |t |ƒ|gd}t |ƒH| ¡|D]}|  |||t|ƒƒ¡qœ|  | ¡d¡Wdƒn1sÜ0YdS)N)r^óyózrJúimport os, socket, sys, timerKúfd = int(sys.argv[1])ú family = %súsock_type = %srLrMz)wr = socket.fromfd(fd, family, sock_type)ú os.close(fd)zwith wr:z for data in datas:z( # let the parent block on recv()z time.sleep(sleep_time)z wr.sendall(data)rOr)ÚsocketrirRrSrTÚintÚfamilyÚtyper-Úfilenor%rUr rVrXr8) rZ recv_funcrYrZr[r0Úfdrr\rrrÚ _test_recv¼s8    ð zSocketEINTRTest._test_recvcCs| tjj¡dSr")rwrqÚrecvrrrrÚ test_recvàszSocketEINTRTest.test_recvÚrecvmsgzneeds recvmsg()cCs| dd„¡dS)NcSs| |¡dSr )rz©Úsockr\rrrr@år6z.SocketEINTRTest.test_recvmsg..)rwrrrrÚ test_recvmsgãszSocketEINTRTest.test_recvmsgc Cs(t ¡\}}| |j¡dtjd}d ddddt|jƒdt|j ƒd |j d tjdd dd d dddddddddddddf¡}|  ¡}|j |t |ƒ|gd}t|ƒh| ¡d}|t|ƒkrô||t|ƒ|d…ƒ} || durìt|ƒn| 7}q¸| | ¡d¡Wdƒn1s0YdS)Nsxyzr2rJrlrKrmrnrorMzdata = b"xyz" * %sr_z)rd = socket.fromfd(fd, family, sock_type)rpzwith rd:z$ # let the parent block on send()rNz' received_data = bytearray(data_len)z n = 0z while n < data_len:z8 n += rd.recv_into(memoryview(received_data)[n:])zif received_data != data:z0 raise Exception("recv error: %s vs %s bytes"z5 % (len(received_data), data_len))rOr)rqrirRrSrZ SOCK_MAX_SIZErTrrrsrtr-rur%rUr rXrbrVr8) rZ send_funcrYrZr\r0rvrrcÚsentrrrÚ _test_sendçsL     è  zSocketEINTRTest._test_sendcCs| tjj¡dSr")rrqÚsendrrrrÚ test_sendszSocketEINTRTest.test_sendcCs| tjj¡dSr")rrqÚsendallrrrrÚ test_sendallszSocketEINTRTest.test_sendallÚsendmsgzneeds sendmsg()cCs| dd„¡dS)NcSs | |g¡Sr")r„r{rrrr@r6z.SocketEINTRTest.test_sendmsg..)rrrrrÚ test_sendmsgszSocketEINTRTest.test_sendmsgc Cs°t tjdf¡}| |j¡| ¡d}d dddtjd|d|jdd d d d f ¡}|  |¡}t |ƒ4|  ¡\}}| ¡|  |  ¡d¡Wdƒn1s¢0YdS) Nrr rJzimport socket, timerKz host = %rz port = %srMz# let parent block on accept()r`z,with socket.create_connection((host, port)):rN)rqÚ create_serverrZHOSTrRrSÚ getsocknamerTr-r%r ÚacceptrVr8)rr|Úportr0rZ client_sockr4rrrÚ test_accepts(  ö   zSocketEINTRTest.test_accepté r2Úmkfifozneeds mkfifo()c CsÔtj}t |¡zt |¡Wn2tyP}z| d|¡WYd}~n d}~00| tj|¡d ddd|d|j dddd|f ¡}|  |¡}t |ƒ(||ƒ|  |  ¡d ¡Wdƒn1sÆ0YdS) Nzos.mkfifo(): %srJúimport os, timerKz path = %arMz# let the parent blockr`r)rÚTESTFNÚunlinkr=rŒÚPermissionErrorZskipTestrRrTr-r%r rVr8)rZdo_open_close_readerZdo_open_close_writerÚfilenameÚer0rrrrÚ _test_open;s, $÷  zSocketEINTRTest._test_opencCst|dƒ}| ¡dS)NÚw)ÚopenrS)rÚpathÚfprrrÚ python_openZs zSocketEINTRTest.python_openÚdarwinz+hangs under macOS; see bpo-25234, bpo-35363cCs| d|j¡dS)Nzfp = open(path, 'r') fp.close())r“r˜rrrrÚ test_open^sÿzSocketEINTRTest.test_opencCst |tj¡}t |¡dSr")r=r•ÚO_WRONLYrS)rr–rvrrrÚos_opendszSocketEINTRTest.os_opencCs| d|j¡dS)Nz,fd = os.open(path, os.O_RDONLY) os.close(fd))r“rœrrrrÚ test_os_openhsÿzSocketEINTRTest.test_os_openN)r)r*r+r,rerfrgrqrwryr}rrrƒr…rŠrZrequires_freebsd_versionr=r“r˜ÚskipIfrÚplatformršrœrrrrrrh¸s2 # .    ÿ  ÿrhc@seZdZdZdd„ZdS)Ú TimeEINTRTestz" EINTR tests for the time module. cCs:t ¡}t |j¡| ¡t ¡|}| ||j¡dSr")ÚtimeÚ monotonicÚsleepr-r!ÚassertGreaterEqual©rÚt0ÚdtrrrÚ test_sleepss   zTimeEINTRTest.test_sleepN)r)r*r+r,r¨rrrrr osr Úpthread_sigmaskzneed signal.pthread_sigmask()c@sLeZdZdZdd„Ze eedƒd¡dd„ƒZ e eedƒd¡d d „ƒZ d S) ÚSignalEINTRTestz$ EINTR tests for the signal module. c Csàtj}t ¡}t |dd„¡}| tj||¡d ddt ¡dt|ƒd|jdd f¡}t tj |g¡}| tjtj |g¡t   ¡}|  |¡}t|ƒ$||ƒt   ¡|} Wdƒn1sÂ0Y| | ¡d ¡dS) NcWsdSr"r)r'rrrr@‡r6z/SignalEINTRTest.check_sigwait..rJrzpid = %sz signum = %srMr`zos.kill(pid, signum)r)rÚSIGUSR1r=ÚgetpidrRrTrrr-r©Ú SIG_BLOCKÚ SIG_UNBLOCKr¡r¢r%r rVr8) rr9rrBZ old_handlerr0Zold_maskr¦rr§rrrÚ check_sigwaitƒs(  ú   *zSignalEINTRTest.check_sigwaitÚ sigwaitinfozneed signal.sigwaitinfo()cCsdd„}| |¡dS)NcSst |g¡dSr")rr°©rrrrr9¡sz3SignalEINTRTest.test_sigwaitinfo..wait_func©r¯©rr9rrrÚtest_sigwaitinfožsz SignalEINTRTest.test_sigwaitinfoÚ sigtimedwaitcCsdd„}| |¡dS)NcSst |gd¡dS)Ng^@)rrµr±rrrr9©sz4SignalEINTRTest.test_sigtimedwait..wait_funcr²r³rrrÚtest_sigtimedwait¦sz!SignalEINTRTest.test_sigtimedwaitN) r)r*r+r,r¯rerfrgrr´r¶rrrrrª{s ÿ  ÿrªc@s’eZdZdZdd„Ze ejdkd¡e  e e dƒd¡dd „ƒƒZ e  e e d ƒd ¡d d „ƒZ e  e e dƒd¡dd„ƒZe  e e dƒd¡dd„ƒZdS)ÚSelectEINTRTestz$ EINTR tests for the select module. cCs@t ¡}t ggg|j¡t ¡|}| ¡| ||j¡dSr")r¡r¢Úselectr-r!r¤r¥rrrÚ test_select³s  zSelectEINTRTest.test_selectr™z(poll may fail on macOS; see issue #28087Úpollzneed select.pollcCsFt ¡}t ¡}| |jd¡t ¡|}| ¡| ||j¡dS©Ng@@)r¸rºr¡r¢r-r!r¤©rZpollerr¦r§rrrÚ test_pollºs  zSelectEINTRTest.test_pollÚepollzneed select.epollcCsNt ¡}| |j¡t ¡}| |j¡t ¡|}| ¡|  ||j¡dSr") r¸r¾rRrSr¡r¢rºr-r!r¤r¼rrrÚ test_epollÆs   zSelectEINTRTest.test_epollÚkqueuezneed select.kqueuecCsRt ¡}| |j¡t ¡}| dd|j¡t ¡|}| ¡|  ||j¡dSr ) r¸rÀrRrSr¡r¢Zcontrolr-r!r¤)rrÀr¦r§rrrÚ test_kqueueÑs  zSelectEINTRTest.test_kqueueÚdevpollzneed select.devpollcCsRt ¡}| |j¡t ¡}| |jd¡t ¡|}| ¡|  ||j¡dSr») r¸rÂrRrSr¡r¢rºr-r!r¤r¼rrrÚ test_devpollÜs  zSelectEINTRTest.test_devpollN)r)r*r+r,r¹reržrrŸrfrgr¸r½r¿rÁrÃrrrrr·¯s ÿ   r·c@s8eZdZdd„Ze e ¡dkd¡dd„ƒZdd„Z d S) Ú FNTLEINTRTestc Cs:| tjtj¡d ddtjd|d|jf¡}t ¡}| |¡}t |ƒØt tjdƒ¢}t ¡|}|dkr|t d|ƒ‚z,||t j t jBƒ||t jƒt d ¡Wq\ty¾YqÀYq\0||t j ƒt ¡|}| ||j¡| ¡Wdƒn1s0Y| ¡Wdƒn1s,0YdS) NrJzimport fcntl, timezwith open('%s', 'wb') as f:z fcntl.%s(f, fcntl.LOCK_EX)z time.sleep(%s)ÚwbgN@z failed to sync child in %.1f secg{®Gáz„?)rRrrrŽrTr-r¡r¢r%r r•Ú ExceptionÚfcntlÚLOCK_EXÚLOCK_NBÚLOCK_UNr£ÚBlockingIOErrorr¤r!r8)rZ lock_funcZ lock_namer0Z start_timerÚfr§rrrÚ_lockés2ü         (zFNTLEINTRTest._lockZAIXzAIX returns PermissionErrorcCs| tjd¡dS)NÚlockf)rÍrÇrÎrrrrÚ test_lockf szFNTLEINTRTest.test_lockfcCs| tjd¡dS)NÚflock)rÍrÇrÐrrrrÚ test_flock szFNTLEINTRTest.test_flockN) r)r*r+rÍreržrŸÚsystemrÏrÑrrrrrÄès  rÄÚ__main__) r,Ú contextlibrrÇr=rŸr¸rrqr%rr¡reÚtestrZ test.supportrrÚcontextmanagerr rfrgZTestCaser r/rhr rªr·rÄr)ÚmainrrrrÚsH     'h7  ÿ/8)