Current File : //proc/self/root/lib/python3/dist-packages/twisted/internet/__pycache__/process.cpython-312.pyc
�

Ϫ�f�����UdZddlmZddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlmZddl
mZmZmZmZmZded<ded<es		dd	lmZmZdd
lmZddlmZmZmZddlm Z dd
l!m"Z"ddl#m$Z$m%Z%ddl&m'Z'm(Z(ddl)m*Z*ddl+m,Z,e*jZ�red��	ddl.Z/e/Z.	ddl0Z1ddl2Z2e1Z0ejfZ3iZ4ded<d&d�Z5d�Z6d�Z7Gd�dejp�Z9Gd�dejp�Z:Gd�de �Z;Gd�d�Z<e<�Z=d �Z>										d'd!�Z?ee"�Gd"�d#e;��Z@ee"�Gd$�d%ejpe;��ZAy#e$rY��wxYw#e$rdZ.Y��wxYw#e$rdZ0Y��wxYw)(z�
UNIX Process management.

Do NOT use this module directly - use reactor.spawnProcess() instead.

Maintainer: Itamar Shtull-Trauring
�)�annotationsN)�defaultdict)�
TYPE_CHECKING�Dict�List�Optional�Tuple�int�	_PS_CLOSE�_PS_DUP2)�POSIX_SPAWN_CLOSE�POSIX_SPAWN_DUP2)�implementer)�abstract�error�fdesc)�BaseProcess)�IProcessTransport)�CONNECTION_DONE�CONNECTION_LOST)�failure�log)�platform)�	switchUIDz^twisted.internet.process does not work on Windows. Use the reactor.spawnProcess() API instead.zDict[int, _BaseProcess]�reapProcessHandlersc�h�ttj��D]}|j��y)z(
    Reap all registered processes.
    N)�listr�values�reapProcess)�processs �:/usr/lib/python3/dist-packages/twisted/internet/process.py�reapAllProcessesr"Hs.���+�2�2�4�5��������c�8�|tvrtd��	tj|tj�\}}|r|j�y|t|<y#t
$r6t
jd|�d��t
j�|�Yyd}Y�\wxYw)z�
    Register a process handler for the given pid, in case L{reapAllProcesses}
    is called.

    @param pid: the pid of the process.
    @param process: a process handler.
    z.Try to register an already registered process.�Failed to reap �:N)
r�RuntimeError�os�waitpid�WNOHANG�
BaseExceptionr�msg�err�processEnded)�pidr �auxPID�statuss    r!�registerReapProcessHandlerr2Rs����!�!��K�L�L�	����C����4��������V�$�$+��C� �������/�#��a�(�)����	��;�����s�'A�8B�B�Bc�P�|tvrt||k(std��t|=y)zd
    Unregister a process handler previously registered with
    L{registerReapProcessHandler}.
    z+Try to unregister a process not registered.N)rr')r/r s  r!�unregisterReapProcessHandlerr4ms.��

�&�&�+>�s�+C�w�+N��H�I�I��C� r#c�B�eZdZdZdZdZdZdd�Zd�Zd�Z	d�Z
d	�Zd
�Zy)
�
ProcessWritera�
    (Internal) Helper class to write into a Process's input pipe.

    I am a helper which describes a selectable asynchronous writer to a
    process's input pipe, including stdin.

    @ivar enableReadHack: A flag which determines how readability on this
        write descriptor will be handled.  If C{True}, then readability may
        indicate the reader for this write descriptor has been closed (ie,
        the connection has been lost).  If C{False}, then readability events
        are ignored.
    �rFc���tjj||�tj|�||_||_||_tjtj|j��j�sd|_n/|rd|_n%	tj|j�d�|jr|j#�yy#t $r
d|_Y�0wxYw)zJ
        Initialize, specifying a Process instance to connect to.
        FTrN)r�FileDescriptor�__init__r�setNonBlocking�proc�name�fd�stat�S_ISFIFOr(�fstat�fileno�st_mode�enableReadHack�read�OSError�startReading)�self�reactorr<r=rB�
forceReadHacks      r!r:zProcessWriter.__init__�s���	���(�(��w�7�
���V�$���	���	�����}�}�R�X�X�d�k�k�m�4�<�<�=�#(�D��
�"&�D��
+�������
�q�)�
���������	�
+�&*��#�
+�s�$C � C3�2C3c��|jS)z<
        Return the fileno() of my process's stdin.
        �r>�rHs r!rBzProcessWriter.fileno��
���w�w�r#c��tj|j|�}|t|�k(r|jr|j�|S�z6
        Write some data to the open process.
        )r�	writeToFDr>�lenrDrG)rH�data�rvs   r!�
writeSomeDatazProcessWriter.writeSomeData�s>���_�_�T�W�W�d�
+��
��T��?�t�2�2�
�����	r#c�d�|j�tjj||�y�N)�stopReadingrr9�write�rHrSs  r!rYzProcessWriter.write�s$���������%�%�d�D�1r#c�H�|jrtS|j�y)a�
        The only way a write pipe can become "readable" is at EOF, because the
        child has closed it, and we're using a reactor which doesn't
        distinguish between readable and closed (such as the select reactor).

        Except that's not true on linux < 2.6.11. It has the following
        characteristics: write pipe is completely empty => POLLOUT (writable in
        select), write pipe is not completely empty => POLLIN (readable in
        select), write pipe's reader closed => POLLIN|POLLERR (readable and
        writable in select)

        That's what this funky code is for. If linux was not broken, this
        function could be simply "return CONNECTION_LOST".
        N)rDrrXrMs r!�doReadzProcessWriter.doRead�s�����"�"����r#c���tj|j�tjj||�|jj|j|�y)z=
        See abstract.FileDescriptor.connectionLost.
        N)	r�setBlockingr>rr9�connectionLostr<�childConnectionLostr=�rH�reasons  r!r_zProcessWriter.connectionLost�sD��	���$�'�'�"����.�.�t�V�<��	�	�%�%�d�i�i��8r#N)F)
�__name__�
__module__�__qualname__�__doc__�	connected�icrDr:rBrUrYr\r_�r#r!r6r6ws6����I�	
�B��N� �>�
�2��(
9r#r6c�>�eZdZdZdZd�Zd�Zd�Zd�Zd�Z	d�Z
d	�Zy
)�
ProcessReaderzx
    ProcessReader

    I am a selectable representation of a process's output pipe, such as
    stdout and stderr.
    Tc��tjj||�tj|�||_||_||_|j�y)zA
        Initialize, specifying a process to connect to.
        N)	rr9r:rr;r<r=r>rG)rHrIr<r=rBs     r!r:zProcessReader.__init__�sI��	���(�(��w�7�
���V�$���	���	�������r#c��|jS)z=
        Return the fileno() of my process's stderr.
        rLrMs r!rBzProcessReader.fileno�rNr#c��|dk(sJ�tS)Nr#)rrZs  r!rUzProcessReader.writeSomeData�s���s�{��{��r#c�V�tj|j|j�S)z@
        This is called when the pipe becomes readable.
        )r�
readFromFDr>�dataReceivedrMs r!r\zProcessReader.doReads!���������):�):�;�;r#c�P�|jj|j|�yrW)r<�childDataReceivedr=rZs  r!rqzProcessReader.dataReceiveds���	�	�#�#�D�I�I�t�4r#c���|jrc|jsVd|_|j�|jj	d|j
t
jt��yyy)Nr7r)	rg�
disconnectingrXrI�	callLaterr_r�FailurerrMs r!�loseConnectionzProcessReader.loseConnection
sT���>�>�$�"4�"4�!"�D�������L�L�"�"��4�&�&�����(H�
�#5�>r#c��tjj||�|jj	|j
|�y)zk
        Close my end of the pipe, signal the Process (which signals the
        ProcessProtocol).
        N)rr9r_r<r`r=ras  r!r_zProcessReader.connectionLosts2��
	���.�.�t�V�<��	�	�%�%�d�i�i��8r#N)rcrdrerfrgr:rBrUr\rqrxr_rir#r!rkrk�s1����I�	���<�5��9r#rkc�\�eZdZUdZdZded<dZd�Zd�Zd�Z	d�Z
d	�Zd
�Zd�Z
d�Zdd
�Zy)�_BaseProcessz0
    Base class for Process and PTYProcess.
    Nz
Optional[int]r1c��		tj|jtj�\}}|rt||�|j�yy#t$r+}|j
t
jk(rd}n�Yd}~�Pd}~wwxYw#t$r<tjd|j�d��tj�d}Y��wxYw)a
        Try to reap a process (without blocking) via waitpid.

        This is called when sigchild is caught or a Process object loses its
        "connection" (stdout is closed) This ought to result in reaping all
        zombie processes, since it will be called twice as often as it needs
        to be.

        (Unfortunately, this is a slightly experimental approach, since
        UNIX has no way to be really sure that your process is going to
        go away w/o blocking.  I don't want to block.)
        Nr%r&)
r(r)r/r*rF�errno�ECHILDr+rr,r-r4r.)rHr/r1�es    r!rz_BaseProcess.reapProcess#s���	�
� �j�j����2�:�:�>���V��(��d�3����f�%����
��7�7�e�l�l�*��C����
���	��G�G�o�d�h�h�Z�q�1�2��G�G�I��C�	�s0�1A�	B	�!B�?B�B	�	B�AC�Cc���dx}}tj|�rtj|�}ntj|�}|s|rt	j
|||�St	j|�SrW)r(�	WIFEXITED�WEXITSTATUS�WTERMSIGr�ProcessTerminated�ProcessDone)rHr1�exitCode�sigs    r!�
_getReasonz_BaseProcess._getReasonAs_�����3�
�<�<����~�~�f�-�H��+�+�f�%�C��s��*�*�8�S�&�A�A�� � ��(�(r#c��|dvrttd|���}|j�
t��	t	j
|j|�y#t$r-}|jtjk(r
t���d}~wwxYw)a*
        Send the given signal C{signalID} to the process. It'll translate a
        few signals ('HUP', 'STOP', 'INT', 'KILL', 'TERM') from a string
        representation to its int value, otherwise it'll pass directly the
        value provided

        @type signalID: C{str} or C{int}
        )�HUP�STOP�INT�KILL�TERM�SIGN)	�getattr�signalr/�ProcessExitedAlreadyr(�killrFr}�ESRCH)rH�signalIDrs   r!�
signalProcessz_BaseProcess.signalProcessKsv���=�=��v��X�J�'7�8�H��8�8��&�(�(�	��G�G�D�H�H�h�'���	��w�w�%�+�+�%�*�,�,���		�s� A�	B�(B�Bc���tdtj�D]M}tj|�tjk(s�*tj|tj
��Oy�Nr7)�ranger��NSIG�	getsignal�SIG_IGN�SIG_DFL)rH�	signalnums  r!�_resetSignalDispositionz$_BaseProcess._resetSignalDisposition`sG���q�&�+�+�.�	9�I����	�*�f�n�n�<��
�
�i����8�	9r#c��y)a0
        Try to use posix_spawnp() instead of fork(), if possible.

        This implementation returns False because the non-PTY subclass
        implements the actual logic; we can't yet use this for pty processes.

        @return: a boolean indicating whether posix_spawnp() was used or not.
        Fri)rH�path�uid�gid�
executable�args�environment�kwargss        r!�_trySpawnInsteadOfForkz#_BaseProcess._trySpawnInsteadOfForkks��r#c	��|j|||||||�rytj�}tj�	t	j
�|_|jdk(rT	tjd�|jdi|��|j||||||�t	j0d
�	|rtj2�d|_y#t$r�	tjt	jdd�d��}	dj|t!|�t#|��}
|	j%|
�t'j(|	��|	j+�t-d	�D]}t	j.|��n#t$rYnwxYwY��wxYw#t$r|rtj2��wxYw)
a�
        Fork and then exec sub-process.

        @param path: the path where to run the new process.
        @type path: L{bytes} or L{unicode}

        @param uid: if defined, the uid used to run the new process.
        @type uid: L{int}

        @param gid: if defined, the gid used to run the new process.
        @type gid: L{int}

        @param executable: the executable to run in a new process.
        @type executable: L{str}

        @param args: arguments used to create the new process.
        @type args: L{list}.

        @param environment: environment used for the new process.
        @type environment: L{dict}.

        @param kwargs: keyword arguments to L{_setupChild} method.
        Nr��wbzutf-8)�encodingz)Upon execvpe {} {} in environment id {}
:��file�r7���ri)r��gc�	isenabled�disabler(�forkr/�sys�settrace�_setupChild�
_execChildr+�io�
TextIOWrapper�fdopen�format�str�idrY�	traceback�	print_exc�flushr��close�_exit�enabler1)rHr�r�r�r�r�r�r��collectorEnabled�stderrr,r>s            r!�_forkz_BaseProcess._forkxs���2�&�&��#�s�J��k�6�
�
��<�<�>��
�
�
��D	��w�w�y�D�H��x�x�1�}�+��L�L��&�$�D�$�$�.�v�.��O�O�D�#�s�J��k�R�V�������I�I�K�����_%�&��""$�!1�!1�"�)�)�A�t�2D�w�!W��N�V�V�&��D�	�2�k�?������S�)�!�+�+��8�����"'��(�)�B��H�H�R�L�)��(�����G&��1�	���	�	���		�sC�F(�+=C�	F%�&B,F�F%�	F�F%�F�F%�$F%�(!G	c��t��)zB
        Setup the child process. Override in subclasses.
        ��NotImplementedError)rHr�r�s   r!r�z_BaseProcess._setupChild�s
��"�#�#r#c�,�|rtj|�|�|�b|�tj�}|�tj�}tjd�tj
d�t
||�tj|||�y)z?
        The exec() which is done in the forked child.
        Nr)r(�chdir�geteuid�getegid�setuid�setgidr�execvpe)rHr�r�r�r�r�r�s       r!r�z_BaseProcess._execChild�sk����H�H�T�N��?�c�o��{��j�j�l���{��j�j�l���I�I�a�L��I�I�a�L��c�3��
�
�
�:�t�[�1r#c�x�dj|jj|j|j�S)z5
        String representation of a process.
        z<{} pid={} status={}>)r��	__class__rcr/r1rMs r!�__repr__z_BaseProcess.__repr__�s2��'�-�-��N�N�#�#��H�H��K�K�
�	
r#)�returnr�)rcrdrerfr1�__annotations__r/rr�r�r�r�r�r�r�r�rir#r!r{r{sG���!�F�M� �
�C�&�<)��*	9��i�V$�2�"
r#r{c�h�eZdZdZej
ZejZeZd�Z	d�Z
d�Zd�Zd�Z
d�Zy)	�_FDDetectorav
    This class contains the logic necessary to decide which of the available
    system techniques should be used to detect the open file descriptors for
    the current process. The chosen technique gets monkey-patched into the
    _listOpenFDs method of this class so that the detection only needs to occur
    once.

    @ivar listdir: The implementation of listdir to use. This gets overwritten
        by the test cases.
    @ivar getpid: The implementation of getpid to use, returns the PID of the
        running process.
    @ivar openfile: The implementation of open() to use, by default the Python
        builtin.
    c�T�|j|j|jg|_yrW)�_procFDImplementation�_devFDImplementation�_fallbackFDImplementation�_implementationsrMs r!r:z_FDDetector.__init__s'���&�&��%�%��*�*�!
��r#c�L�|j�|_|j�S)z�
        Return an iterable of file descriptors which I{may} be open in this
        process.

        This will try to return the fewest possible descriptors without missing
        any.
        )�_getImplementation�_listOpenFDsrMs r!r�z_FDDetector._listOpenFDs!s$��!�3�3�5���� � �"�"r#c���|jD]5}	|�}|jdd�5|�}ddd�|k7s�3|cSS#t$rY�EwxYw#1swY�%xYw)a�
        Pick a method which gives correct results for C{_listOpenFDs} in this
        runtime environment.

        This involves a lot of very platform-specific checks, some of which may
        be relatively expensive.  Therefore the returned method should be saved
        and re-used, rather than always calling this method to determine what it
        is.

        See the implementation for the details of how a method is selected.
        z	/dev/null�rN)r�r+�openfile)rH�impl�before�afters    r!r�z_FDDetector._getImplementation,sx���)�)�	�D�
�������{�C�0�
����
������	����!�
��
��
�
�s�A�A�	A�A�A	c�b�d}|j|�D�cgc]
}t|���}}|Scc}w)z�
        Simple implementation for systems where /dev/fd actually works.
        See: http://www.freebsd.org/cgi/man.cgi?fdescfs
        z/dev/fd)�listdirr
)rH�dnamer>�results    r!r�z _FDDetector._devFDImplementationIs3��
��$(�L�L��$7�8�b�#�b�'�8��8��
��9s�,c��d|j�fz}|j|�D�cgc]
}t|���c}Scc}w)zk
        Simple implementation for systems where /proc/pid/fd exists (we assume
        it works).
        z/proc/%d/fd)�getpidr�r
)rHr�r>s   r!r�z!_FDDetector._procFDImplementationRs8��
����� 0�0��"&�,�,�u�"5�6�B��B��6�6��6s�=c��	ddl}td|j|j�d�}t|�S#t$rd}Yt|�SwxYw)au
        Fallback implementation where either the resource module can inform us
        about the upper bound of how many FDs to expect, or where we just guess
        a constant maximum if there is no resource module.

        All possible file descriptors from 0 to that upper bound are returned
        with no attempt to exclude invalid file descriptor values.
        rNir7)�resource�min�	getrlimit�
RLIMIT_NOFILE�ImportErrorr�)rHr��maxfdss   r!r�z%_FDDetector._fallbackFDImplementationZs[��	N����x�1�1�(�2H�2H�I�!�L�M�F��V�}����	��F��V�}��	�s�9�A�AN)rcrdrerfr(r�r��openr�r:r�r�r�r�r�rir#r!r�r�s>��
� �j�j�G�
�Y�Y�F��H�
�	#��:�7�r#r�c�*�tj�S)zZ
    Use the global detector object to figure out which FD implementation to
    use.
    )�detectorr�rir#r!r�r�rs��
� � �"�"r#c�F���t|�}tt�}|j�D]\}}||j	|��t|���t|j
��z��t|j��z�d�d��fd�}g}	i}
t|j��D]�\}}||j|�||r |�x}|
|<|	j	|||f�||
vr4|	j	||
||f�||r�`|	j	||
|f��w||k(r*||s��|�}|	j|||f|||f||fg���|	j	|||f���|j�D] \}
}|
|vs�|r�|	j	||
f��"|	S)a`
    Get the C{file_actions} parameter for C{posix_spawn} based on the
    parameters describing the current process state.

    @param fdState: A list of 2-tuples of (file descriptor, close-on-exec
        flag).

    @param doClose: the integer to use for the 'close' instruction

    @param doDup2: the integer to use for the 'dup2' instruction
    rc�F����vr
�dz
���vr�
�j���Sr�)�add)�	allocated�nextFDs��r!�
allocateFDz#_getFileActions.<locals>.allocateFD�s/����	�!��a�K�F��	�!��
�
�f���
r#)r�r
)�dictrr�items�append�setr�keys�sorted�remove�extend)�fdState�childToParentFD�doClose�doDup2�fdStateDict�parentToChildren�inChild�inParentr�r��relocations�new�tempFD�eachFD�
uninheritabler�r�s               @@r!�_getFileActionsrzs����"�w�-�K�-8��->��,�2�2�4�3������"�)�)�'�2�3��K� �I�
��_�+�+�-�.�.�I�
��_�)�)�+�,�,�I�
�F��%'�F��K�#�O�$9�$9�$;�<�!;������"�)�)�'�2��G�$�)3��5�C�+�g�&��M�M�6�7�C�0�1��{�"��M�M�6�;�x�#8�'�B�C�#�H�-��
�
�w��H�(=�>�?��7�"��x�(�
(�\�F��M�M�#�X�v�6�#�V�W�5�$�f�-����
�
�v�x��9�:�C!;�F"-�!2�!2�!4�-���
���(���M�M�7�F�+�,�-��Mr#c��eZdZdZdZdZdZdZeZ	e
Z			dd�Zd�Z
eedd��[
d�Zd	�Zd
�Zd�Zd�Zd
�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Z d�Z!y)�Processa�
    An operating-system Process.

    This represents an operating-system process with arbitrary input/output
    pipes connected to it.  Those pipes may represent standard input, standard
    output, and standard error, or any other file descriptor.

    On UNIX, this is implemented using posix_spawnp() when possible (or fork(),
    exec(), pipe() and fcntl() when not).  These calls may not exist elsewhere
    so this code is not cross-platform.  (also, windows can only select on
    sockets...)
    Fr�Nc
	����||_|s(d|	j�vsJ�d|	j�vsJ�tj||�i|_i}
|	�dddd�}	|j
}|rt
d|	�g��fd�}i}
	|	j�D]�\}}|rt
d|z|�|dk(r'|�\}}|rt
d||fz�||
|<||
|<�C|dk(r'|�\}}|rt
d||fz�||
|<||
|<�ot|�tk(s
J|�d	���||
|<��|rt
d
|
�|rt
d|
�|j|||||||
��||_|
j�D]v\}}tj|
|�|	|dk(r#|j||||�}||j|<|	|dk(s�R|j!||||d
��}||j|<�x	|j�|jj#|�t)|j*|�y#t$r�D]}tj|���wxYw#t$rt%j&�Y�`wxYw)�
        Spawn an operating-system process.

        This is where the hard work of disconnecting all currently open
        files / forking / executing the new process happens.  (This is
        executed automatically when a Process is instantiated.)

        This will also run the subprocess as a given user ID and group ID, if
        specified.  (Implementation Note: this doesn't support all the arcane
        nuances of setXXuid on UNIX: it will assume that either your effective
        or real UID is 0.)
        r��wN)rr7r��childFDsc�`��tj�\}}�j||g�||fSrW)r(�piper)r�r�_openedPipess  �r!rzProcess.__init__.<locals>.pipes-����7�7�9�D�A�q�����A��'��a�4�Kr#z[%d]zreadFD=%d, writeFD=%dz should be an int�fdmap�helpers)rT)rJ)�_reactorrr{r:�pipes�debug�printr��typer
r�r+r(r��proto�processReaderFactory�processWriterFactory�makeConnectionrr-r2r/)rHrIr�r�r�r�r#r�r�rrr rr�childFD�target�readFD�writeFD�parentFD�reader�writerrs                     @r!r:zProcess.__init__�s����0 ��
���h�o�o�/�/�/�/��h�o�o�/�/�/�/����d�E�*���
���������H��
�
����*�h�'���	���	�#+�>�>�#3�
,������&�7�*�F�3��S�=�&*�f�O�F�G���5���8I�I�J�%,�E�'�N�'-�G�G�$��s�]�&*�f�O�F�G���5���8I�I�J�%+�E�'�N�'.�G�G�$���<�3�.�N�6�*�<M�0N�N�.�%+�E�'�N�'
,�(��g�u�%���i��)�
�J�J�t�S�#�z�4��E�J�R���
�")����
	-��G�X��H�H�U�7�^�$��� �C�'��2�2�7�D�'�8�T��&,��
�
�7�#��� �C�'��2�2��T�7�H�D�3���'-��
�
�7�#�
	-�	��z�z�%��
�
�)�)�$�/�	#�4�8�8�T�2��A�	�$�
�������
��	��2�	��G�G�I�	�s�>CH#�%'I
�#'I
�
I-�,I-c���|�Z|�X|�?tjj|�tjjd�k7st|jdd�ry|jd�}g}	t
�D]I}
	tj|
tjtj�}|	j|
|f��K|�tj}tdtj�D�cgc]*}tj |�tj"k(r|��,}
}tj$|||t'|	|t(t*��|
��|_d|_y	#t$rY��wxYwcc}w)
z�
        Try to use posix_spawnp() instead of fork(), if possible.

        @return: a boolean indicating whether posix_spawnp() was used or not.
        �.�_neverUseSpawnFrr7)rr)�file_actions�	setsigdefr�T)r(r��abspathr�r�getr��fcntl�F_GETFD�
FD_CLOEXECr�rF�environr�r�r�r�r��posix_spawnprrrr/r1)rHr�r�r�r�r�r�r�rrr�
isCloseOnExec�everySignal�	setSigDefs              r!r�zProcess._trySpawnInsteadOfForkWsI���_����!�������(=������QT�AU�(U��t�}�}�&6��>���
�
�7�#����"�n�	8�F�
8� %���F�E�M�M�5�CS�CS� T�
�����
�6�7�
	8����*�*�K� %�Q����4�
������,����>�
�
�	�
��?�?����(���	�(�� �
��������/�
��
��
s�?3E"�5/E1�"	E.�-E.r9c�&�|j}|r!tj}|jd�|j	�}t�D]3}||vr�|r|j
�k(r�	tj|��5|rtd|��t|j��D]�}||}||k(r(|rtd|z��tj|��5||j	�vrjtj|�}|rtd||fz��tj|�t!|j#��D]\}	}
|
|k(s�|||	<�|rtd||fz��tj$||���g}|j	�D]+}||vs�||j�vs�|j'|��-|rtd|��|D]}tj|��|j)�y#t$rY���wxYw)	a
        fdmap[childFD] = parentFD

        The child wants to end up with 'childFD' attached to what used to be
        the parent's parentFD. As an example, a bash command run like
        'command 2>&1' would correspond to an fdmap of {0:0, 1:1, 2:1}.
        'command >foo.txt' would be {0:0, 1:os.open('foo.txt'), 2:2}.

        This is accomplished in two steps::

            1. close all file descriptors that aren't values of fdmap.  This
               means 0 .. maxfds (or just the open fds within that range, if
               the platform supports '/proc/<pid>/fd').

            2. for each childFD::

                 - if fdmap[childFD] == childFD, the descriptor is already in
                   place.  Make sure the CLOEXEC flag is not set, then delete
                   the entry from fdmap.

                 - if childFD is in fdmap.values(), then the target descriptor
                   is busy. Use os.dup() to move it elsewhere, update all
                   fdmap[childFD] items that point to it, then close the
                   original. Then fall through to the next case.

                 - now fdmap[childFD] is not in fdmap.values(), and is free.
                   Use os.dup2() to move it to the right place, then close the
                   original.
        zstarting _setupChild
rr�z%d already in placezos.dup(%d) -> %dzos.dup2(%d,%d)�oldN)�debug_childr�r�rYrr�rBr(r�r+r!rrr�_unsetCloseOnExec�duprr��dup2r�r�)rHrr �errfd�destListr>�childr(�	newtarget�c�pr>s            r!r�zProcess._setupChild�s���<� � ����J�J�E��K�K�0�1��<�<�>���.�	�B��X�~����u�|�|�~�-��
������
	���'�5�u�-��E�J�J�L�)�	'�E��5�\�F������/�&�8�u�E��'�'��.��E�L�L�N�*�!#���u�
�I���0�E�9�3E�E�E�R��H�H�U�O� $�U�[�[�]� 3�1���1���:�'0�E�!�H�1���*�f�e�_�<�5�I������&�-	'�@���,�,�.�	#�B���}��U�Z�Z�\�)��J�J�r�N�	#���%��5�)��	�B��H�H�R�L�	�	
�$�$�&��g!�
��
�s�)H�	H�Hc�@�|j|j|�yrW�rrY�rHr'rSs   r!�writeToChildzProcess.writeToChild�s���
�
�7��!�!�$�'r#c�\�||jvr|j|j�yyrW)rrx)rHr's  r!�closeChildFDzProcess.closeChildFD�s*��
�d�j�j� ��J�J�w��.�.�0�!r#c��|jj�D]#}t|t�s�|j	��%yrW)rr�
isinstancerkrX�rHrHs  r!�pauseProducingzProcess.pauseProducing�s1�����"�"�$�	 �A��!�]�+��
�
��	 r#c��|jj�D]#}t|t�s�|j	��%yrW)rrrPrkrGrQs  r!�resumeProducingzProcess.resumeProducing�s2�����"�"�$�	!�A��!�]�+���� �	!r#c�&�|jd�y)zD
        Call this to close standard input on this process.
        rN�rNrMs r!�
closeStdinzProcess.closeStdins��	
���!�r#c�&�|jd�yr�rVrMs r!�closeStdoutzProcess.closeStdout������!�r#c�&�|jd�y�Nr�rVrMs r!�closeStderrzProcess.closeStderr	rZr#c�d�|j�|j�|j�yrW)rWr]rYrMs r!rxzProcess.loseConnections$�������������r#c�^�d|jvr|jdj|�yy�z�
        Call this to write to standard input on this process.

        NOTE: This will silently lose data if there is no standard input.
        rNrJrZs  r!rYz
Process.writes*��
��
�
�?��J�J�q�M����%�r#c��d|jvr |jdj||�y|j�y)z�
        Call this to register producer for standard input.

        If there is no standard input producer.stopProducing() will
        be called immediately.
        rN)r�registerProducer�
stopProducing)rH�producer�	streamings   r!rbzProcess.registerProducers3��
��
�
�?��J�J�q�M�*�*�8�Y�?��"�"�$r#c�\�d|jvr|jdj�yy)z=
        Call this to unregister producer for standard input.rN)r�unregisterProducerrMs r!rgzProcess.unregisterProducer&s(��
��
�
�?��J�J�q�M�,�,�.�r#c�^�d|jvr|jdj|�yyr`)r�
writeSequence)rH�seqs  r!rizProcess.writeSequence,s*��
��
�
�?��J�J�q�M�'�'��,�r#c�<�|jj||�yrW�r#rs)rHr=rSs   r!rszProcess.childDataReceived5s���
�
�$�$�T�4�0r#c��tj|j|j��|j|=	|jj|�|j�y#t$rtj�Y�0wxYwrW)
r(r�rrBr#r`r+rr-�maybeCallProcessEnded)rHr'rbs   r!r`zProcess.childConnectionLost8sm��	������G�$�+�+�-�.��J�J�w��	��J�J�*�*�7�3�	
�"�"�$���	��G�G�I�	�s�A+�+B�
Bc��|jry|js|j�ytj	|�yrW)r�lostProcessrr{rnrMs r!rnzProcess.maybeCallProcessEndedCs4���:�:�����������*�*�4�0r#c��t��rWr�rMs r!�getHostzProcess.getHostP���!�#�#r#c��t��rWr�rMs r!�getPeerzProcess.getPeerTrsr#�NNN)"rcrdrerfr r?r1r/r6r%rkr$r:r�r�r(r�rLrNrRrTrWrYr]rxrYrbrgrirsr`rnrrrurir#r!rr�s����
�E��K�
�F�
�C�(��(��
���v3�p-�^�r�>�4�(�0�"�^'�@(�1� �
!�����
&�
%�/�-�1�	%�1�$�$r#rc�h�eZdZdZdZdZ			dd�Zd�Zd�Zd�Z	d�Z
d	�Zd
�Zd�Z
d�Zd
�Zd�Zd�Zy)�
PTYProcessz<
    An operating-system Process that uses PTY support.
    r�Nc

�>�t�!t|	ttf�st	d��t
jj||�tj||�t|	ttf�r|	\}
}}ntj�\}
}	|j|||||||
|��tj|�tj|
�|
|_|j#�d|_d|_	|j(j+|�t1|j2|�y#t$rBt|	ttf�s*tj|
�tj|��wxYw#t$rt-j.�Y��wxYw)rNz:cannot use PTYProcess on platforms without the pty module.)�masterfd�slavefdr7r�)�ptyrP�tuplerr�rr9r:r{�openptyr�r+r(r�rr;r>rGrgr1r#r&rr-r2r/)
rHrIr�r�r�r�r#r�r��usePTYrzr{�_s
             r!r:zPTYProcess.__init__bs]��0�;�z�&�5�$�-�@�%�L��
�	���(�(��w�7����d�E�*��f�u�d�m�,�#)� �H�g�q� #���
��H�g�	��J�J�������!��
�	
�"	�����
���X�&��������������	��J�J�%�%�d�+�	#�4�8�8�T�2��#�	��f�u�d�m�4�����"�����!��		���	��G�G�I�	�s�D.�<E<�.AE9�<F�Fc��tj|�tj�tj	|t
jd�td�D]}||k7s�	tj|��tj|d�tj|d�tj|d�t�D]}|dkDs�		tj|�� |j�y#t$rY�=wxYw)a9
        Set up child process after C{fork()} but before C{exec()}.

        This involves:

            - closing C{masterfd}, since it is not used in the subprocess

            - creating a new session with C{os.setsid}

            - changing the controlling terminal of the process (and the new
              session) to point at C{slavefd}

            - duplicating C{slavefd} to standard input, output, and error

            - closing all other open file descriptors (according to
              L{_listOpenFDs})

            - re-setting all signal handlers to C{SIG_DFL}

        @param masterfd: The master end of a PTY file descriptors opened with
            C{openpty}.
        @type masterfd: L{int}

        @param slavefd: The slave end of a PTY opened with C{openpty}.
        @type slavefd: L{int}
        �r�rr7r�N)r(r��setsidr5�ioctl�termios�	TIOCSCTTYr�rBr�r+r�)rHrzr{r>s    r!r�zPTYProcess._setupChild�s���6	�����
�	�	��
���G�W�.�.��3���(�	�B��W�}������	�	������
������
�������.�	�B��A�v���H�H�R�L�	�	
�$�$�&��%����s�C8�8	D�Dc��yrWrirMs r!rWzPTYProcess.closeStdin�s��	
r#c��yrWrirMs r!rYzPTYProcess.closeStdout����r#c��yrWrirMs r!r]zPTYProcess.closeStderr�r�r#c�J��tj�j�fd��S)zM
        Called when my standard output stream is ready for reading.
        c�<���jjd|�Sr�rl)rSrHs �r!�<lambda>z#PTYProcess.doRead.<locals>.<lambda>�s���$�*�*�">�">�q�$�"G�r#)rrpr>rMs`r!r\zPTYProcess.doRead�s"�������G�G�G�
�	
r#c��|jS)zR
        This returns the file number of standard output on this process.
        rLrMs r!rBzPTYProcess.fileno�rNr#c�N�|jdk(rtj|�yyr\)rpr{rnrMs r!rnz PTYProcess.maybeCallProcessEnded�s%�����q� ��.�.�t�4�!r#c���tjj||�tj|j
�|xjdz
c_|j�y)zU
        I call this to clean up when one or all of my connections has died.
        r7N)rr9r_r(r�r>rprnras  r!r_zPTYProcess.connectionLost�sG��	���.�.�t�V�<�
����������A����"�"�$r#c�B�tj|j|�SrP)rrQr>rZs  r!rUzPTYProcess.writeSomeDatas�����t�w�w��-�-r#c��t��rWr�)rH�
descriptors  r!rNzPTYProcess.closeChildFDrsr#c��t��rWr�rKs   r!rLzPTYProcess.writeToChildrsr#rv)rcrdrerfr1r/r:r�rWrYr]r\rBrnr_rUrNrLrir#r!rxrxYs]����F�
�C�
���A3�F.'�`
�

�
�
��5�%�.�$�$r#rx)r��None)
rzList[Tuple[int, bool]]rzDict[int, int]rr
rr
r�zList[Tuple[int, ...]])Brf�
__future__rr}r�r�r(r�r?r�r��collectionsr�typingrrrrr	r�r
rrrr��zope.interfacer�twisted.internetrrr�twisted.internet._baseprocessr�twisted.internet.interfacesr�twisted.internet.mainrr�twisted.pythonrr�twisted.python.runtimer�twisted.python.utilr�	isWindowsr|�_ptyr5�_fcntlr�r�rr"r2r4r9r6rkr{r�r�r�rrrxrir#r!�<module>r�s���
�#��	�	�	�
��
��#�=�=���

�
��
�S�'�3�3�5�9�B�'�+�)��8����
�	6���
���C����
�E��1�1��/1��,�1��+�6!�e9�H�+�+�e9�P99�H�+�+�99�xg
�;�g
�Tg�g�T�=��#�J�
#�J�#�J��J�
�	J�
�J�Z
�
��N$�l�N$� �N$�b
�
��s$��(�(�,�s$� �s$��w!�
��
��*��
�C������E��s6�E"�%E.�,E;�"E+�*E+�.E8�7E8�;F�F
¿Qué es la limpieza dental de perros? - Clínica veterinaria


Es la eliminación del sarro y la placa adherida a la superficie de los dientes mediante un equipo de ultrasonidos que garantiza la integridad de las piezas dentales a la vez que elimina en profundidad cualquier resto de suciedad.

A continuación se procede al pulido de los dientes mediante una fresa especial que elimina la placa bacteriana y devuelve a los dientes el aspecto sano que deben tener.

Una vez terminado todo el proceso, se mantiene al perro en observación hasta que se despierta de la anestesia, bajo la atenta supervisión de un veterinario.

¿Cada cuánto tiempo tengo que hacerle una limpieza dental a mi perro?

A partir de cierta edad, los perros pueden necesitar una limpieza dental anual o bianual. Depende de cada caso. En líneas generales, puede decirse que los perros de razas pequeñas suelen acumular más sarro y suelen necesitar una atención mayor en cuanto a higiene dental.


Riesgos de una mala higiene


Los riesgos más evidentes de una mala higiene dental en los perros son los siguientes:

  • Cuando la acumulación de sarro no se trata, se puede producir una inflamación y retracción de las encías que puede descalzar el diente y provocar caídas.
  • Mal aliento (halitosis).
  • Sarro perros
  • Puede ir a más
  • Las bacterias de la placa pueden trasladarse a través del torrente circulatorio a órganos vitales como el corazón ocasionando problemas de endocarditis en las válvulas. Las bacterias pueden incluso acantonarse en huesos (La osteomielitis es la infección ósea, tanto cortical como medular) provocando mucho dolor y una artritis séptica).

¿Cómo se forma el sarro?

El sarro es la calcificación de la placa dental. Los restos de alimentos, junto con las bacterias presentes en la boca, van a formar la placa bacteriana o placa dental. Si la placa no se retira, al mezclarse con la saliva y los minerales presentes en ella, reaccionará formando una costra. La placa se calcifica y se forma el sarro.

El sarro, cuando se forma, es de color blanquecino pero a medida que pasa el tiempo se va poniendo amarillo y luego marrón.

Síntomas de una pobre higiene dental
La señal más obvia de una mala salud dental canina es el mal aliento.

Sin embargo, a veces no es tan fácil de detectar
Y hay perros que no se dejan abrir la boca por su dueño. Por ejemplo…

Recientemente nos trajeron a la clínica a un perro que parpadeaba de un ojo y decía su dueño que le picaba un lado de la cara. Tenía molestias y dificultad para comer, lo que había llevado a sus dueños a comprarle comida blanda (que suele ser un poco más cara y llevar más contenido en grasa) durante medio año. Después de una exploración oftalmológica, nos dimos cuenta de que el ojo tenía una úlcera en la córnea probablemente de rascarse . Además, el canto lateral del ojo estaba inflamado. Tenía lo que en humanos llamamos flemón pero como era un perro de pelo largo, no se le notaba a simple vista. Al abrirle la boca nos llamó la atención el ver una muela llena de sarro. Le realizamos una radiografía y encontramos una fístula que llegaba hasta la parte inferior del ojo.

Le tuvimos que extraer la muela. Tras esto, el ojo se curó completamente con unos colirios y una lentilla protectora de úlcera. Afortunadamente, la úlcera no profundizó y no perforó el ojo. Ahora el perro come perfectamente a pesar de haber perdido una muela.

¿Cómo mantener la higiene dental de tu perro?
Hay varias maneras de prevenir problemas derivados de la salud dental de tu perro.

Limpiezas de dientes en casa
Es recomendable limpiar los dientes de tu perro semanal o diariamente si se puede. Existe una gran variedad de productos que se pueden utilizar:

Pastas de dientes.
Cepillos de dientes o dedales para el dedo índice, que hacen más fácil la limpieza.
Colutorios para echar en agua de bebida o directamente sobre el diente en líquido o en spray.

En la Clínica Tus Veterinarios enseñamos a nuestros clientes a tomar el hábito de limpiar los dientes de sus perros desde que son cachorros. Esto responde a nuestro compromiso con la prevención de enfermedades caninas.

Hoy en día tenemos muchos clientes que limpian los dientes todos los días a su mascota, y como resultado, se ahorran el dinero de hacer limpiezas dentales profesionales y consiguen una mejor salud de su perro.


Limpiezas dentales profesionales de perros y gatos

Recomendamos hacer una limpieza dental especializada anualmente. La realizamos con un aparato de ultrasonidos que utiliza agua para quitar el sarro. Después, procedemos a pulir los dientes con un cepillo de alta velocidad y una pasta especial. Hacemos esto para proteger el esmalte.

La frecuencia de limpiezas dentales necesaria varía mucho entre razas. En general, las razas grandes tienen buena calidad de esmalte, por lo que no necesitan hacerlo tan a menudo e incluso pueden pasarse la vida sin requerir una limpieza. Sin embargo, razas pequeñas como el Yorkshire o el Maltés, deben hacérselas todos los años desde cachorros si se quiere conservar sus piezas dentales.

Otro factor fundamental es la calidad del pienso. Algunas marcas han diseñado croquetas que limpian la superficie del diente y de la muela al masticarse.

Ultrasonido para perros

¿Se necesita anestesia para las limpiezas dentales de perros y gatos?

La limpieza dental en perros no es una técnica que pueda practicarse sin anestesia general , aunque hay veces que los propietarios no quieren anestesiar y si tiene poco sarro y el perro es muy bueno se puede intentar…… , pero no se va a poder pulir ni acceder a todas la zona de la boca …. Además los limpiadores dentales van a irrigar agua y hay riesgo de aspiración a vías respiratorias si no se realiza una anestesia correcta con intubación traqueal . En resumen , sin anestesia no se va hacer una correcta limpieza dental.

Tampoco sirve la sedación ya que necesitamos que el animal esté totalmente quieto, y el veterinario tenga un acceso completo a todas sus piezas dentales y encías.

Alimentos para la limpieza dental

Hay que tener cierto cuidado a la hora de comprar determinados alimentos porque no todos son saludables. Algunos tienen demasiado contenido graso, que en exceso puede causar problemas cardiovasculares y obesidad.

Los mejores alimentos para los dientes son aquellos que están elaborados por empresas farmacéuticas y llevan componentes químicos con tratamientos específicos para el diente del perro. Esto implica no solo limpieza a través de la acción mecánica de morder sino también un tratamiento antibacteriano para prevenir el sarro.

Conclusión

Si eres como la mayoría de dueños, por falta de tiempo , es probable que no estés prestando la suficiente atención a la limpieza dental de tu perro. Por eso te animamos a que comiences a limpiar los dientes de tu perro y consideres atender a su higiene bucal con frecuencia.

Estas simples medidas pueden conllevar a que tu perro tenga una vida más larga y mucho más saludable.

Si te resulta imposible introducir un cepillo de dientes a tu perro en la boca, pásate con él por clínica Tus Veterinarios y te explicamos cómo hacerlo.

Necesitas hacer una limpieza dental profesional a tu mascota?
Llámanos al 622575274 o contacta con nosotros

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

¡Hola!