grthtrhthjhtyjytjytkergtrhtrjytjerhrfh4:24 29/09/2026a q©jùEã@sdZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl mZmZmZddlmZmZe d¡jZeddœdd„ZdZe e¡Zd ZGd d „d ejƒZGd d „d ejƒZ Gdd„dƒZ!Gdd„deej"ƒZ"Gdd„deƒZ#Gdd„dƒZ$dS)zKBi-directional asyncio.Transport implementations based on file descriptors.éN)ÚAnyÚClassVarÚSequenceé)Ú JsonObjectÚget_int)ÚargsÚreturncGst|Ždkrtdƒ‚dS)Nrzprctl() failed)Ú sys_prctlÚOSError)r©r ú6/usr/lib/python3.9/site-packages/cockpit/transports.pyÚprctls ricsÚeZdZUdZeeed<ejed<ej ed<ded<eed<eed<e ed <e ed <e ed <d Z e ed <dHejej eeddœ‡fdd„ Z ddœdd„Z e dœdd„Zddœdd„Zddœdd„Zddœdd„Zddœdd „ZdId!dd"œd#d$„Ze dœd%d&„Zddœd'd(„Zedœd)d*„Zd+dœd,d-„ZdJd.d.dd/œd0d1„Zddœd2d3„Zddœd4d5„Zddœd6d7„Zedd8œd9d:„Zedd8œd;d<„Zddœd=d>„Zej dœd?d@„Z!e dœdAdB„Z"ej ddCœdDdE„Z#ddœdFdG„Z$‡Z%S)KÚ _TransportiÚ BLOCK_SIZEÚ_loopÚ _protocolzcollections.deque[bytes] | NoneÚ_queueÚ_in_fdÚ_out_fdÚ_closingÚ _is_readingÚ_eofFÚ _eio_is_eoféÿÿÿÿNzdict[str, object] | None)ÚloopÚprotocolÚin_fdÚout_fdÚextracs†tƒ |¡||_||_t d||||¡d|_d|_d|_d|_ ||_ ||_ t   |d¡||krnt   |d¡|j |¡| ¡dS)Nz/Created transport %s for protocol %s, fds %d %dF)ÚsuperÚ__init__rrÚloggerÚdebugrrrrrrÚosÚ set_blockingZconnection_madeÚresume_reading)Úselfrrrrr©Ú __class__r r r!6s    z_Transport.__init__©r c Csât d||j|j¡zt |jtj¡}Wnfty<YdSt yŽ}z<|j rb|j t j krbd}n|  |¡WYd}~dSWYd}~n d}~00|dkr¶t dt|ƒ¡|j |¡n(t d¡| ¡|j ¡}|sÞ| ¡dS)NzRead ready on %s %s %dóz read %d bytesz got EOF)r"r#rrr$ÚreadrrÚBlockingIOErrorr rÚerrnoZEIOÚabortÚlenZ data_receivedÚ _close_readerZ eof_receivedÚclose)r'ÚdataÚexcZ keep_openr r r Ú _read_readyQs$  $  z_Transport._read_readycCs|jS©N)r©r'r r r Ú is_readingjsz_Transport.is_readingcCs| ¡d|_dS©Nr)Ú pause_readingrr7r r r r1msz_Transport._close_readercCs|jr|j |j¡d|_dS©NF)rrÚ remove_readerrr7r r r r:qsz_Transport.pause_readingcCs,|js(|jdkr(|j |j|j¡d|_dS)NrT)rrrÚ add_readerr5r7r r r r&vsz_Transport.resume_readingcCsdSr6r r7r r r Ú_close~sz_Transport._closezException | None)r4r cCs4d|_| ¡| ¡|j |jj|¡| ¡dS©NT)rr1Ú_remove_write_queuerZ call_soonrZconnection_lostr>)r'r4r r r r/�s z_Transport.abortcCst‚dSr6©ÚNotImplementedErrorr7r r r Ú can_write_eofˆsz_Transport.can_write_eofcCs6d|_|jdur&t d|¡| ¡n t d|¡dS)NTz%s got EOF. closing backend.z,%s got EOF. bytes in queue, deferring close)rrr"r#Ú_write_eof_nowr7r r r Ú write_eof‹s    z_Transport.write_eofcCs"|jdurdStdd„|jDƒƒS)Nrcss|]}t|ƒVqdSr6)r0)Ú.0Úblockr r r Ú —r+z3_Transport.get_write_buffer_size..)rÚsumr7r r r Úget_write_buffer_size”s z _Transport.get_write_buffer_sizeztuple[int, int]cCsdS)N)rrr r7r r r Úget_write_buffer_limits™sz"_Transport.get_write_buffer_limitsú int | None)ÚhighÚlowr cCsdSr6r )r'rMrNr r r Úset_write_buffer_limitsœsz"_Transport.set_write_buffer_limitscCst‚dSr6rAr7r r r rD sz_Transport._write_eof_nowc Cst d|¡zt |j|j¡}WnDty6d}Yn0tyd}z| |¡WYd}~dSd}~00t d|¡|rÆ|j  ¡}t |ƒ|kr¬t d¡|j  ||d…¡qÆ|t |ƒ8}t d|¡qr|j�s t d¡|  ¡|j �rút d¡| ¡|j�r | ¡dS)Nz%s _write_readyrz, successfully wrote %d bytes from the queuez incomplete block. Stop.z& removed complete block. %d remains.z%s queue drained.z'%s queue drained. closing backend now.)r"r#r$Úwritevrrr-r r/Úpopleftr0Ú appendleftr@rrDr)r'Ún_bytesr4rGr r r Ú _write_ready£s2          z_Transport._write_readycCs,|jdur(|j ¡|j |j¡d|_dSr6)rrZresume_writingrZ remove_writerrr7r r r r@Äs  z_Transport._remove_write_queue)r3r cCs>t d||j¡|j |j|j¡t |f¡|_|j   ¡dS)Nz!%s creating write queue for fd %s) r"r#rrZ add_writerrTÚ collectionsÚdequerrZ pause_writing©r'r3r r r Ú_create_write_queueÊsz_Transport._create_write_queuec CsÜ|jrt d|j¡dS|jdurb|j |¡t|jƒtkr^d |j¡}|j  ¡|j |¡dSzt   |j|¡}WnDt yŠd}Yn0t y¸}z| |¡WYd}~dSd}~00|t|ƒkrØ| ||d…¡dS)Nz+ignoring write() to closing transport fd %ir+r)rr"r#rrÚappendr0ÚIOV_MAXÚjoinÚclearr$Úwriter-r r/rX)r'r3Zall_datarSr4r r r r]Ñs&        z_Transport.writecCs2|jr dSd|_| ¡|jdur&dS| ¡dSr?)rr1rr/r7r r r r2ñs z_Transport.closecCs|jSr6)rr7r r r Ú get_protocolþsz_Transport.get_protocolcCs|jSr6)rr7r r r Ú is_closingsz_Transport.is_closing)rr cCst‚dSr6rA)r'rr r r Ú set_protocolsz_Transport.set_protocolcCs | ¡dSr6)r>r7r r r Ú__del__sz_Transport.__del__)rrN)N)NN)&Ú__name__Ú __module__Ú __qualname__rrÚintÚ__annotations__ÚasyncioÚAbstractEventLoopÚProtocolÚboolrr!r5r8r1r:r&r>r/rCrErJrKrOrDrTr@ÚbytesrXr]r2Z BaseProtocolr^r_r`raÚ __classcell__r r r(r r'sP    üü !  rc@seZdZdZddœdd„ZdS)ÚSubprocessProtocolzBAn extension to asyncio.Protocol for use with SubprocessTransport.Nr*cCst‚dS)z"Called when subprocess has exited.NrAr7r r r Úprocess_exited sz!SubprocessProtocol.process_exited)rbrcrdÚ__doc__rnr r r r rm srmc@seZdZedœdd„ZdS)Ú WindowSize)ÚvaluecCst|dƒ|_t|dƒ|_dS)NÚrowsÚcols)rrrrs)r'rqr r r r!s zWindowSize.__init__N)rbrcrdrr!r r r r rpsrpcs(eZdZUdZdZded<dZded<dZded<ded <d d œee d œd d„Z dddœdd„Z d ddœe j eee ededœ‡fdd„Zeddœdd„Zedœdd„Zddœdd„Zedœd d!„Zddœd"d#„Zee jd$œd%d&„Zejdd'œd(d)„Zddœd*d+„Zddœd,d-„Zddœd.d/„Z ‡Z!S)0ÚSubprocessTransportaéA bi-directional transport speaking with stdin/out of a subprocess. Note: this is not really a normal SubprocessTransport. Although it implements the entire API of asyncio.SubprocessTransport, it is not designed to be used with asyncio.SubprocessProtocol objects. Instead, it pair with normal Protocol objects which also implement the SubprocessProtocol defined in this module (which only has a process_exited() method). Whatever the protocol writes is sent to stdin, and whatever comes from stdout is given to the Protocol via the .data_received() function. If stderr is configured as a pipe, the transport will separately collect data from it, making it available via the .get_stderr() method. NrLÚ_pty_fdzsubprocess.Popen[bytes] | NoneÚ_processÚ _returncodezSpooler | NoneÚ_stderrF©Úreset©rzr cCs(|jdur |jj|d�jdd�SdSdS)NryÚreplace)ÚerrorsÚ)rxÚgetÚdecode)r'rzr r r Ú get_stderr-s zSubprocessTransport.get_stderrzsubprocess.Popen[bytes])Úprocessr c süddœ‡fdd„ ‰ddœ‡‡‡‡fdd„ }ttddœ‡‡‡fdd„ }zt ˆj¡‰ˆj ˆ|¡Wn”ttfyöd }tˆj|dƒ}|duräz t   ¡}Wn.tyÈ}zt d ƒ|‚WYd}~n d}~00|  ˆj¡t ˆj||ƒ| ˆj|¡Yn0dS) Nr*cs"t dˆj¡ˆjsˆj ¡dS)NzProcess exited with status %d)r"r#rwrrrnr r7r r Ú flag_exit4sz1SubprocessTransport.watch_exit..flag_exitcs\t ˆjd¡\}}zt |¡ˆ_Wnty:|ˆ_Yn0ˆj ˆ¡t ˆ¡ˆƒdS©Nr) r$ÚwaitpidÚpidÚwaitstatus_to_exitcoderwÚ ValueErrorrr<r2)r†Ústatus©rƒZpidfdr‚r'r r Ú pidfd_ready:s    z3SubprocessTransport.watch_exit..pidfd_ready)r†Úcoder cs|ˆ_ˆƒdSr6©rw)r†rŒ)rƒr‚r'r r Úchild_watch_firedEsz9SubprocessTransport.watch_exit..child_watch_firedZ!_cockpit_transports_child_watcherz&pidfd support required on Python 3.14+)rer$Ú pidfd_openr†rr=ÚAttributeErrorr ÚgetattrrgZSafeChildWatcherÚ RuntimeErrorZ attach_loopÚsetattrZadd_child_handler)r'r‚r‹rŽZquarkZwatcherÚer rŠr Ú watch_exit3s"      zSubprocessTransport.watch_exit)ÚptyÚwindowzWindowSize | None)rrrr–r—Úkwargsc  sþddœ‡fdd„ }ˆr|t ¡\|_}|dur6| |¡||d<tj|f|||ddœ|¤Ž|_t |¡|j|j} } d|_n8tj|ftj tj |dœ|¤Ž|_|jj   ¡} |jj   ¡} |jj durÖt||jj   ¡ƒ|_nd|_tƒ ||| | ¡| |j¡dS)Nr*cs$tttjƒˆr t dtjd¡dSr„)rÚ SET_PDEATHSIGÚsignalÚSIGTERMÚfcntlÚioctlÚtermiosZ TIOCSCTTYr ©r–r r Ú preexec_fnks z0SubprocessTransport.__init__..preexec_fnÚstderrT)ÚstdinÚstdoutr Zstart_new_session)r¢r£r )r$ÚopenptyruÚset_window_sizeÚ subprocessÚPopenrvr2rÚPIPEr£Úfilenor¢r¡ÚSpoolerrxr r!r•) r'rrrr–r—r˜r Z session_fdrrr(rŸr r!as6  þþ ÿÿ   zSubprocessTransport.__init__)Úsizer c Cs$t |jtjt d|j|j¡¡dS)NZ2H4x) rœr�ruržZ TIOCSWINSZÚstructÚpackrrrs)r'r«r r r r¥�sz#SubprocessTransport.set_window_sizer*cCs |jjduSr6)rvr¢r7r r r rC“sz!SubprocessTransport.can_write_eofcCs|jj ¡d|_dSr9)rvr¢r2rr7r r r rD—s z"SubprocessTransport._write_eof_nowcCs|jjSr6)rvr†r7r r r Úget_pid�szSubprocessTransport.get_pidcCs|jSr6r�r7r r r Úget_returncode¡sz"SubprocessTransport.get_returncode)Úfdr cCst‚dSr6rA)r'r°r r r Úget_pipe_transport¤sz&SubprocessTransport.get_pipe_transport)Úsigr cCsp|jdur t d||jj¡dSz&t |jj|¡t d||jj¡Wn$tyjt d||jj¡Yn0dS)Nz3won't attempt %s to process %i. It exited already.zsent %s to process %iz3can't send %s to process %i. It's exited just now.)rwr"r#rvr†r$ÚkillÚProcessLookupError)r'r²r r r Ú send_signal§s  zSubprocessTransport.send_signalcCs| tj¡dSr6)rµršr›r7r r r Ú terminate¿szSubprocessTransport.terminatecCs| tj¡dSr6)rµršÚSIGKILLr7r r r r³ÂszSubprocessTransport.killcCsz|jdurt |j¡d|_|jdurv|jjdurF|jj ¡d|j_z | ¡Wn"tytt d|jj ¡Yn0dS)Nzcan't kill %i due to EPERM) rur$r2rvr¢r¶ÚPermissionErrorr"r#r†r7r r r r>Ås       zSubprocessTransport._close)"rbrcrdrorurfrvrwrjÚstrr�r•rgrhrmrrr!rpr¥rCrDrer®r¯Ú Transportr±ršZSignalsrµr¶r³r>rlr r r(r rts6    3úù.rtcsNeZdZdZd ejejeedœ‡fdd„ Ze dœdd „Z d dœd d „Z ‡Z S)ÚStdioTransportzÈA bi-directional transport that corresponds to stdin/out. Can talk to just about anything: - files - pipes - character devices (including terminals) - sockets rr)rrr¢r£cstƒ ||||¡dSr6)r r!)r'rrr¢r£r(r r r!ÞszStdioTransport.__init__r*cCsdSr;r r7r r r rCászStdioTransport.can_write_eofNcCs tdƒ‚dS)NzCan't write EOF to stdout)r’r7r r r rDäszStdioTransport._write_eof_now)rr) rbrcrdrorgrhrirer!rjrCrDrlr r r(r r»Ôs r»c@sŒeZdZUdZejed<eed<ded<ejedœdd„Zd d œd d „Z e d œd d„Z ddœe e dœdd„Z d d œdd„Zd d œdd„Zd S)rªzŽConsumes data from an fd, storing it in a buffer. This makes a copy of the fd, so you don't have to worry about holding it open. rÚ_fdz list[bytes]Ú _contents)rr°cCs@||_d|_g|_t |¡|_t |jd¡| |j|j¡dS)NrF)rr¼r½r$Údupr%r=r5)r'rr°r r r r!ós  zSpooler.__init__Nr*cCs^zt |jd¡}Wn(ty&YdSty:d}Yn0|dkrR|j |¡n| ¡dS)Ni r+)r$r,r¼r-r r½rYr2rWr r r r5ýs   zSpooler._read_readycCs,|jdkrdSt |jgggd¡gggfkS)NrFr)r¼Úselectr7r r r Ú _is_ready s zSpooler._is_readyFryr{cCs,| ¡r| ¡qd |j¡}|r(g|_|S)Nr+)rÀr5r[r½)r'rzÚresultr r r rs   z Spooler.getcCs.|jdkr*|j |j¡t |j¡d|_dSr9)r¼rr<r$r2r7r r r r2s  z Spooler.closecCs | ¡dSr6)r2r7r r r raszSpooler.__del__)rbrcrdrorgrhrfrer!r5rjrÀrkrr2rar r r r rªès    rª)%rorgrUZctypesr.rœZloggingr$r¿ršr¬r¦ržÚtypingrrrZjsonutilrrZCDLLrr rer™Z getLoggerrbr"rZrºrrirmrprtr»rªr r r r Ús6  e=