f ž _Fc@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)Zkill)Ú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ÚsignumZframerrrÚ sighandler3ózEINTRBaseTest.sighandlercCsBd|_t tj|j¡|_t tj|j|j¡t j ddt j ddS)NriXT)ZexitZfile) r ÚsignalÚSIGALRMrÚ orig_handlerrÚ ITIMER_REALÚ signal_delayÚ signal_periodÚ faulthandlerZdump_traceback_laterÚsysZ __stderr__©r rrrÚsetUp6s ÿÿzEINTRBaseTest.setUpcCst tjdd¡dS©Nr)rrrrrrrÚ stop_alarmAózEINTRBaseTest.stop_alarmcCs$| ¡t tj|j¡t ¡dS©N)rrrrrZcancel_dump_traceback_laterrrrrÚtearDownEszEINTRBaseTest.tearDowncOs tjdf|}tj|fi|¤ŽS)Nz-c)rZ executableÚ subprocessZPopen)r ÚargsZkwZcmd_argsrrrr JózEINTRBaseTest.subprocessN) Ú__name__Ú __module__Ú __qualname__Ú__doc__rrÚ sleep_timerrZ staticmethodrrr 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_processSó zOSEINTRTest.new_sleep_processcsDd}‡fdd„t|ƒDƒ}t|ƒD] }|ƒq"|D] }| ¡q2dS)Nécsg|] }ˆ ¡‘qSr)r*)Z.0Ú_rrrZ Yóz3OSEINTRTest._test_wait_multiple..)ZrangeÚwait)r Ú wait_funcZnumZ processesr-rrrrÚ_test_wait_multipleWs  zOSEINTRTest._test_wait_multiplecCs| tj¡dSr)r1Úosr/rrrrÚ test_wait`rzOSEINTRTest.test_waitÚwait3zrequires wait3()cCó| dd„¡dS)NcSs t d¡Sr)r2r4rrrrÚer.z(OSEINTRTest.test_wait3..)r1rrrrÚ test_wait3crzOSEINTRTest.test_wait3cCs| ¡}||jƒ| ¡dSr)r*Úpidr/)r r0rrrrÚ_test_wait_singlegs zOSEINTRTest._test_wait_singlecCr5)NcSó t |d¡Sr)r2Zwaitpid©r8rrrr6nr.z*OSEINTRTest.test_waitpid..©r9rrrrÚ test_waitpidmrzOSEINTRTest.test_waitpidÚwait4zrequires wait4()cCr5)NcSr:r)r2r>r;rrrr6rr.z(OSEINTRTest.test_wait4..r<rrrrÚ test_wait4przOSEINTRTest.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)©Zpass_fdsr) r2ÚpipeÚ addCleanupÚcloseÚjoinr'r ÚstrrÚ assertEqualZreadÚlenr/)r ÚrdÚwrÚdatasr)rÚ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óxr@zimport io, os, sys, timerAzrd = int(sys.argv[1])rCzdata = 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))rEr)r2rFrGrHrZ PIPE_MAX_SIZErIr'r rJrrLZwriteÚ memoryviewrKr/)r rMrNrPr)rÚwrittenrrrÚ test_write‘s>  í   zOSEINTRTest.test_writeN)r#r$r%r&r*r1r3ÚunittestÚ skipUnlessÚhasattrr2r7r9r=r?rQrWrrrrr(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)rRsyszr@úimport os, socket, sys, timerAúfd = int(sys.argv[1])ú family = %súsock_type = %srBrCz)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)rEr)Úsocketr\rGrHrIÚintÚfamilyÚtyper'Úfilenor rJrrKrLr/) r Z recv_funcrMrNrOr)ÚfdrrPrrrÚ _test_recv¼s8    ð zSocketEINTRTest._test_recvcCó| tjj¡dSr)rhrbZrecvrrrrÚ test_recvàrzSocketEINTRTest.test_recvÚrecvmsgzneeds recvmsg()cCr5)NcSs| |¡dSr)rk©ÚsockrPrrrr6år.z.SocketEINTRTest.test_recvmsg..)rhrrrrÚ test_recvmsgãrzSocketEINTRTest.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)Nsxyzr,r@r]rAr^r_r`rCzdata = b"xyz" * %srSz)rd = socket.fromfd(fd, family, sock_type)razwith rd:z$ # let the parent block on send()rDz' 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))rEr)rbr\rGrHrZ SOCK_MAX_SIZErIrcrdrer'rfr rJrrLrUrKr/) r Z send_funcrMrNrPr)rgrrVZsentrrrÚ _test_sendçsL     è  zSocketEINTRTest._test_sendcCrir)rorbZsendrrrrÚ test_sendrzSocketEINTRTest.test_sendcCrir)rorbZsendallrrrrÚ test_sendallrzSocketEINTRTest.test_sendallÚsendmsgzneeds sendmsg()cCr5)NcSs | |g¡Sr)rrrlrrrr6r.z.SocketEINTRTest.test_sendmsg..)rorrrrÚ test_sendmsgrzSocketEINTRTest.test_sendmsgc Cs°t tjdf¡}| |j¡| ¡d}d dddtjd|d|jdd d d d f ¡}|  |¡}t |ƒ4|  ¡\}}| ¡|  |  ¡d¡Wdƒn1s¢0YdS) Nrr r@zimport socket, timerAz host = %rz port = %srCz# let parent block on accept()rTz,with socket.create_connection((host, port)):rD)rbZ create_serverrZHOSTrGrHZ getsocknamerIr'r rZacceptrKr/)r rmZportr)rZ client_sockr-rrrÚ test_accepts(  ö   zSocketEINTRTest.test_accepti r,Ú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(): %sr@úimport os, timerAz path = %arCz# let the parent blockrTr)rÚTESTFNÚunlinkr2ruZPermissionErrorZskipTestrGrIr'r rrKr/)r Zdo_open_close_readerZdo_open_close_writerZfilenameZer)rrrrÚ _test_open;s, $÷  zSocketEINTRTest._test_opencCst|dƒ}| ¡dS)NZw)ÚopenrH)r ÚpathZfprrrÚ python_openZr+zSocketEINTRTest.python_openÚdarwinz+hangs under macOS; see bpo-25234, bpo-35363cCó| d|j¡dS)Nzfp = open(path, 'r') fp.close())ryr|rrrrÚ test_open^óÿzSocketEINTRTest.test_opencCst |tj¡}t |¡dSr)r2rzZO_WRONLYrH)r r{rgrrrÚos_opendr"zSocketEINTRTest.os_opencCr~)Nz,fd = os.open(path, os.O_RDONLY) os.close(fd))ryrrrrrÚ test_os_openhr€zSocketEINTRTest.test_os_openN)r#r$r%r&rXrYrZrbrhrjrnrorprqrsrtrZrequires_freebsd_versionr2ryr|ÚskipIfrÚplatformrrr‚rrrrr[¸s2 # .    ÿ  ÿr[c@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&rrrrrr…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) NcWsdSrr)r!rrrr6‡r.z/SignalEINTRTest.check_sigwait..r@rvzpid = %sz signum = %srCrTzos.kill(pid, signum)r)rZSIGUSR1r2ZgetpidrGrIrcr'rŽZ SIG_BLOCKZ SIG_UNBLOCKr†r‡r rrKr/) r r0rr8Z old_handlerr)Zold_maskr‹rrŒrrrÚ check_sigwaitƒs(  ú   *zSignalEINTRTest.check_sigwaitÚ sigwaitinfozneed signal.sigwaitinfo()cCódd„}| |¡dS)NcSst |g¡dSr)rr‘©rrrrr0¡rz3SignalEINTRTest.test_sigwaitinfo..wait_func©r©r r0rrrÚtest_sigwaitinfožóz SignalEINTRTest.test_sigwaitinfoÚ sigtimedwaitcCr’)NcSst |gd¡dS)Ng^@)rr˜r“rrrr0©rz4SignalEINTRTest.test_sigtimedwait..wait_funcr”r•rrrÚtest_sigtimedwait¦r—z!SignalEINTRTest.test_sigtimedwaitN) r#r$r%r&rrXrYrZrr–r™rrrrr{s ÿ  ÿrc@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'rr‰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›rr†r‡r'rr‰©r Zpollerr‹rŒrrrÚ test_pollºs  zSelectEINTRTest.test_pollÚepollzneed select.epollcCsNt ¡}| |j¡t ¡}| |j¡t ¡|}| ¡|  ||j¡dSr) r›r¡rGrHr†r‡rr'rr‰rŸrrrÚ test_epollÆs   zSelectEINTRTest.test_epollÚkqueuezneed select.kqueuecCsRt ¡}| |j¡t ¡}| dd|j¡t ¡|}| ¡|  ||j¡dSr ) r›r£rGrHr†r‡Zcontrolr'rr‰)r r£r‹rŒrrrÚ test_kqueueÑó  zSelectEINTRTest.test_kqueueÚdevpollzneed select.devpollcCsRt ¡}| |j¡t ¡}| |jd¡t ¡|}| ¡|  ||j¡dSrž) r›r¦rGrHr†r‡rr'rr‰rŸrrrÚ test_devpollÜr¥zSelectEINTRTest.test_devpollN)r#r$r%r&rœrXrƒrr„rYrZr›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) Nr@zimport fcntl, timezwith open('%s', 'wb') as f:z fcntl.%s(f, fcntl.LOCK_EX)z time.sleep(%s)ZwbgN@z failed to sync child in %.1f secg{®Gáz„?)rGrrxrwrIr'r†r‡r rrzZ ExceptionÚfcntlZLOCK_EXZLOCK_NBZLOCK_UNrˆZBlockingIOErrorr‰rr/)r Z lock_funcZ lock_namer)Z start_timerZfrŒrrrÚ_lockés2ü         (zFNTLEINTRTest._lockZAIXzAIX returns PermissionErrorcCó| tjd¡dS)NÚlockf)rªr©r¬rrrrÚ test_lockf rzFNTLEINTRTest.test_lockfcCr«)NÚflock)rªr©r®rrrrÚ test_flock rzFNTLEINTRTest.test_flockN) r#r$r%rªrXrƒr„Zsystemr­r¯rrrrr¨ès  r¨Z__main__) r&Z contextlibrr©r2r„r›rrbr rr†rXZtestrZ test.supportrrZcontextmanagerrrYrZZTestCaser r(r[r…rršr¨r#ZmainrrrrZsH     'h7  ÿ/8)