
9Mc           @   s1  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 y d d l	 Z	 Wn e
 k
 r e Z	 n Xy d d l Z d d l Z Wn e
 k
 r e Z n Xd d l m Z d d l m Z m Z d d l m Z d d l m Z m Z m Z d d l m Z m Z d d l m Z d d	 l m Z e j  Z  i  Z! d
   Z" d   Z# d   Z$ d   Z% e%   d e j& f d     YZ' d e j& f d     YZ( d e e) f d     YZ* d e) f d     YZ+ e+   Z, d   Z- d e* f d     YZ. d e j& e* f d     YZ/ d S(   s   
UNIX Process management.

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

Maintainer: Itamar Shtull-Trauring
iN(   t
   implements(   t   logt   failure(   t	   switchUID(   t   fdesct   abstractt   error(   t   CONNECTION_LOSTt   CONNECTION_DONE(   t   BaseProcess(   t   IProcessTransportc          C   s%   x t  j   D] }  |  j   q Wd S(   s(   
    Reap all registered processes.
    N(   t   reapProcessHandlerst   valuest   reapProcess(   t   process(    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyt   reapAllProcesses)   s    c         C   s   |  t  k r t d   n  y t j |  t j  \ } } Wn( t j d |   t j   d } n X| r{ | j	 |  n
 | t  |  <d S(   s   
    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.
    s.   Try to register an already registered process.s   Failed to reap %d:N(
   R   t   RuntimeErrort   ost   waitpidt   WNOHANGR   t   msgt   errt   Nonet   processEnded(   t   pidR   t   auxPIDt   status(    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyt   registerReapProcessHandler1   s    

c         C   s6   |  t  k o t  |  | k s+ t d   n  t  |  =d S(   sd   
    Unregister a process handler previously registered with
    L{registerReapProcessHandler}.
    s+   Try to unregister a process not registered.N(   R   R   (   R   R   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyt   unregisterReapProcessHandlerH   s    c          C   sy   t  j   \ }  } t  j | d  t j | g g  g  d  \ } } } | rU t a n t a t  j |   t  j |  d S(   s   
    On some Linux version, write-only pipe are detected as readable. This
    function is here to check if this bug is present or not.

    See L{ProcessWriter.doRead} for a more detailed explanation.
    t   ai    N(   R   t   pipet   writet   selectt   Truet   brokenLinuxPipeBehaviort   Falset   close(   t   rt   wt   readst   writest   exes(    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyt   detectLinuxBrokenPipeBehaviorS   s    $	t   ProcessWriterc           B   sY   e  Z d  Z d Z d Z e Z e d  Z d   Z d   Z	 d   Z
 d   Z d   Z RS(	   s  
    (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.
    i   i    c         C   s   t  j j |  |  t j |  | |  _ | |  _ | |  _ t j	 t
 j |  j    j  sh t |  _ nI | rz t |  _ n7 y t
 j |  j   d  Wn t k
 r t |  _ n X|  j r |  j   n  d S(   sJ   
        Initialize, specifying a Process instance to connect to.
        i    N(   R   t   FileDescriptort   __init__R   t   setNonBlockingt   proct   namet   fdt   statt   S_ISFIFOR   t   fstatt   filenot   st_modeR#   t   enableReadHackR!   t   readt   OSErrort   startReading(   t   selft   reactorR/   R0   R5   t   forceReadHack(    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR-   {   s    			!	c         C   s   |  j  S(   s<   
        Return the fileno() of my process's stdin.
        (   R1   (   R;   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR5      s    c         C   sA   t  j |  j |  } | t |  k r= |  j r= |  j   n  | S(   s6   
        Write some data to the open process.
        (   R   t	   writeToFDR1   t   lenR7   R:   (   R;   t   datat   rv(    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyt   writeSomeData   s    c         C   s!   |  j    t j j |  |  d  S(   N(   t   stopReadingR   R,   R   (   R;   R@   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR      s    
c         C   sg   |  j  rY t rR |  j } t j | g | g g  d  \ } } } | rV | rV t Sqc t Sn
 |  j   d S(   s}  
        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".

        BUG: We call select no matter what the reactor.
        If the reactor is pollreactor, and the fd is > 1024, this will fail.
        (only occurs on broken versions of linux, though).
        i    N(   R7   R"   R1   R    R   RC   (   R;   R1   R%   R&   t   x(    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyt   doRead   s    		'c         C   s=   t  j |  j  t j j |  |  |  j j |  j |  d S(   s=   
        See abstract.FileDescriptor.connectionLost.
        N(	   R   t   setBlockingR1   R   R,   t   connectionLostR/   t   childConnectionLostR0   (   R;   t   reason(    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyRG      s    (   t   __name__t
   __module__t   __doc__t	   connectedt   icR#   R7   R-   R5   RB   R   RE   RG   (    (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR+   j   s   				t   ProcessReaderc           B   sS   e  Z d  Z d Z d   Z d   Z d   Z d   Z d   Z d   Z	 d   Z
 RS(	   sx   
    ProcessReader

    I am a selectable representation of a process's output pipe, such as
    stdout and stderr.
    i   c         C   sI   t  j j |  |  t j |  | |  _ | |  _ | |  _ |  j   d S(   sA   
        Initialize, specifying a process to connect to.
        N(	   R   R,   R-   R   R.   R/   R0   R1   R:   (   R;   R<   R/   R0   R5   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR-      s    			c         C   s   |  j  S(   s=   
        Return the fileno() of my process's stderr.
        (   R1   (   R;   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR5      s    c         C   s   | d k s t   t S(   Nt    (   t   AssertionErrorR   (   R;   R@   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyRB      s    c         C   s   t  j |  j |  j  S(   s@   
        This is called when the pipe becomes readable.
        (   R   t
   readFromFDR1   t   dataReceived(   R;   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyRE      s    c         C   s   |  j  j |  j |  d  S(   N(   R/   t   childDataReceivedR0   (   R;   R@   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyRS     s    c         C   sO   |  j  rK |  j rK d |  _ |  j   |  j j d |  j t j t   n  d  S(   Ni   i    (	   RM   t   disconnectingRC   R<   t	   callLaterRG   R   t   FailureR   (   R;   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyt   loseConnection  s
    	
c         C   s-   t  j j |  |  |  j j |  j |  d S(   sk   
        Close my end of the pipe, signal the Process (which signals the
        ProcessProtocol).
        N(   R   R,   RG   R/   RH   R0   (   R;   RI   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyRG     s    (   RJ   RK   RL   RM   R-   R5   RB   RE   RS   RX   RG   (    (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyRO      s   						t   _BaseProcessc           B   sb   e  Z d  Z d	 Z d	 Z d   Z d   Z d   Z d   Z	 d   Z
 d   Z d   Z d   Z RS(
   s0   
    Base class for Process and PTYProcess.
    c         C   s   yZ y" t  j |  j t  j  \ } } Wn1 t k
 rX } | j t j k rR d } qY   n XWn+ t j	 d |  j  t j
   d } n X| r |  j |  t | |   n  d S(   s  
        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.)
        s   Failed to reap %d:N(   R   R   R   R   R9   t   errnot   ECHILDR   R   R   R   R   R   (   R;   R   R   t   e(    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR     s    "	

c         C   sf   d  } } t j |  r+ t j |  } n t j |  } | sF | rY t j | | |  St j |  S(   N(   R   R   t	   WIFEXITEDt   WEXITSTATUSt   WTERMSIGR   t   ProcessTerminatedt   ProcessDone(   R;   R   t   exitCodet   sig(    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyt
   _getReason<  s    
c         C   sW   | d k r% t  t d | f  } n  |  j d k r@ t    n  t j |  j |  d S(	   s*  
        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}
        t   HUPt   STOPt   INTt   KILLt   TERMs   SIG%sN(   Re   Rf   Rg   Rh   Ri   (   t   getattrt   signalR   R   t   ProcessExitedAlreadyR   t   kill(   R;   t   signalID(    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyt   signalProcessG  s
    	c         C   sO   xH t  d t j  D]4 } t j |  t j k r t j | t j  q q Wd  S(   Ni   (   t   rangeRk   t   NSIGt	   getsignalt   SIG_IGNt   SIG_DFL(   R;   t	   signalnum(    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyt   _resetSignalDispositionW  s    c      	   K   s>  | d
 k	 p | d
 k	 } | r t j   }	 t j   }
 t j   } t j   } | d
 k rc | } n  | d
 k rx |	 } n  t j d  t j d  n  t j	   } t j
   y t j   |  _ WnF | r t j |
 |	  t j | |  n  | r t j   n    n X|  j d k ry= t j d
  |  j |   |  j | | | | | | |  Wn y~ t j d d  } | j d | t |  d t |  f  t j d |  | j   x! t d  D] } t j |  qWWqqXn Xt j d  n  | rt j |
 |	  t j | |  n  | r1t j   n  d	 |  _ d
 S(   s  
        Fork and then exec sub-process.

        @param path: the path where to run the new process.
        @type path: C{str}
        @param uid: if defined, the uid used to run the new process.
        @type uid: C{int}
        @param gid: if defined, the gid used to run the new process.
        @type gid: C{int}
        @param executable: the executable to run in a new process.
        @type executable: C{str}
        @param args: arguments used to create the new process.
        @type args: C{list}.
        @param environment: environment used for the new process.
        @type environment: C{dict}.
        @param kwargs: keyword arguments to L{_setupChild} method.
        i    i   R&   s&   Upon execvpe %s %s in environment %s
:s   id %st   filei   i   iN(   R   R   t   getegidt   getgidt   geteuidt   getuidt   setuidt   setgidt   gct	   isenabledt   disablet   forkR   t   setregidt   setreuidt   enablet   syst   settracet   _setupChildt
   _execChildt   fdopenR   t   strt   idt	   tracebackt	   print_exct   flushRp   R$   t   _exitR   (   R;   t   patht   uidt   gidt
   executablet   argst   environmentt   kwargst
   settingUIDt   curegidt   currgidt   cureuidt   curruidt   collectorEnabledt   stderrR1   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyt   _forkc  s`    		
		
c         O   s   t     d S(   sB   
        Setup the child process. Override in subclasses.
        N(   t   NotImplementedError(   R;   R   R   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR     s    c         C   sC   | r t  j |  n  | r, t | |  n  t  j | | |  d S(   s?   
        The exec() which is done in the forked child.
        N(   R   t   chdirR   t   execvpe(   R;   R   R   R   R   R   R   R   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR     s
    c         C   s   d |  j  j |  j |  j f S(   s5   
        String representation of a process.
        s   <%s pid=%s status=%s>(   t	   __class__RJ   R   R   (   R;   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyt   __repr__  s    N(   RJ   RK   RL   R   R   R   R   Rd   Ro   Rv   R   R   R   R   (    (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyRY     s   					Y		t   _FDDetectorc           B   se   e  Z d  Z e j Z e j Z e Z d   Z d   Z	 d   Z
 d   Z d   Z d   Z d   Z RS(   sy  
    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.

    @ivars listdir: The implementation of listdir to use. This gets overwritten
        by the test cases.
    @ivars getpid: The implementation of getpid to use, returns the PID of the
        running process.
    @ivars openfile: The implementation of open() to use, by default the Python
        builtin.
    c         C   s   |  j    |  _ |  j   S(   sF   
        Figure out which implementation to use, then run it.
        (   t   _getImplementationt   _listOpenFDs(   R;   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR     s    c         C   s   y+ |  j  d  |  j   r# |  j S|  j SWnY y% |  j  d |  j   f  |  j SWq y |  j   |  j SWq |  j SXq Xn Xd S(   s   
        Check if /dev/fd works, if so, use that.  Otherwise, check if
        /proc/%d/fd exists, if so use that.
        
        Otherwise, ask resource.getrlimit, if that throws an exception, then
        fallback to _fallbackFDImplementation.
        s   /dev/fds   /proc/%d/fdN(   t   listdirt   _checkDevFDSanityt   _devFDImplementationt   _fallbackFDImplementationt   getpidt   _procFDImplementationt   _resourceFDImplementation(   R;   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR     s    
c         C   s:   |  j  d  } |  j d d  } |  j  d  } | | k S(   s   
        Returns true iff opening a file modifies the fds visible
        in /dev/fd, as it should on a sane platform.
        s   /dev/fds	   /dev/nullR%   (   R   t   openfile(   R;   t   startt   fpt   end(    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR     s    c         C   s2   d } g  t  j |  D] } t |  ^ q } | S(   s   
        Simple implementation for systems where /dev/fd actually works.
        See: http://www.freebsd.org/cgi/man.cgi?fdescfs
        s   /dev/fd(   R   R   t   int(   R;   t   dnameR1   t   result(    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR     s    (c         C   s9   d t  j   f } g  t  j |  D] } t |  ^ q# S(   sk   
        Simple implementation for systems where /proc/pid/fd exists (we assume
        it works).
        s   /proc/%d/fd(   R   R   R   R   (   R;   R   R1   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR   "  s    c         C   sE   d d l  } | j | j  d d } | d k r; d } n  t |  S(   s   
        Fallback implementation where the resource module can inform us about
        how many FDs we can expect.

        Note that on OS-X we expect to be using the /dev/fd implementation.
        iNi   i   (   t   resourcet	   getrlimitt   RLIMIT_NOFILEt   xrange(   R;   R   t   maxfds(    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR   +  s
    	c         C   s   d } t  |  S(   sn   
        Fallback-fallback implementation where we just assume that we need to
        close 256 FDs.
        i   (   R   (   R;   R   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR   ;  s    (   RJ   RK   RL   R   R   R   t   openR   R   R   R   R   R   R   R   (    (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR     s   						
			c           C   s
   t  j   S(   sZ   
    Use the global detector object to figure out which FD implementation to
    use.
    (   t   detectorR   (    (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR   F  s    t   Processc           B   s   e  Z d  Z e e  e Z e Z d Z d Z
 e Z e Z d d d d  Z d   Z d   Z d   Z d   Z d   Z d   Z d	   Z d
   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z RS(   s  
    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 fork(), exec(), pipe()
    and fcntl(). These calls may not exist elsewhere so this
    code is not cross-platform. (also, windows can only select
    on sockets...)
    ic
      	      s  | s9 d |	 j    k s t  d |	 j    k s9 t  n  t j |  |  i  |  _ i  }
 |	 d k r i d d 6d d 6d d 6}	 n  |  j } | r d G|	 GHn  g      f d   } i  } y=x |	 j   D] \ } } | r d | G| GHn  | d k r4|   \ } } | rd	 | | f GHn  | | | <| |
 | <q | d k r~|   \ } } | rgd	 | | f GHn  | | | <| |
 | <q t |  t	 k st d
 | f  | | | <q W| rd G| GHn  | rd G|
 GHn  |  j
 | | | | | | d | Wn t t j      n X| |  _ x |
 j   D] \ } } t j | |  |	 | d k r}|  j | |  | |  } | |  j | <n  |	 | d k r(|  j | |  | | d t } | |  j | <q(q(Wy& |  j d k	 r|  j j |   n  Wn t j   n Xt |  j |   d S(   s  
        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%   R&   i    i   i   t   childFDsc             s/   t  j   \ }  }   j |  | g  |  | f S(   N(   R   R   t   extend(   R%   R&   (   t   _openedPipes(    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR     s    s   [%d]s   readFD=%d, writeFD=%ds   %r should be an intt   fdmapt   helpersR=   N(   R   RQ   RY   R-   t   pipesR   t   debugt   itemst   typeR   R   t   mapR   R$   t   protot   processReaderFactoryt   processWriterFactoryR!   t   makeConnectionR   R   R   R   (   R;   R<   R   R   R   R   R   R   R   R   R   R   R   R   t   childFDt   targett   readFDt   writeFDt   parentFDt   readert   writer(    (   R   s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR-   f  sv    	
	   
 
"  &		c         C   sT  |  j  } | r( t j } | j d  n  | j   } x\ t   D]Q } | | k rV q> n  | rt | | j   k rt q> n  y t j |  Wq> q> Xq> W| r | d I| IJn  | j	   } | j
   x | D] } | | } | | k r| r | d | IJn  t j |  q | | j   k rt j |  }	 | rJ| d | |	 f IJn  t j |  x6 | j   D]% \ }
 } | | k rd|	 | |
 <qdqdWn  | r| d | | f IJn  t j | |  q Wg  } xE | j   D]7 } | | k r| | j	   k r| j |  qqqW| r(| d I| IJn  x | D] } t j |  q/W|  j   d S(   s  
        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.
        s   starting _setupChild
R   s   %d already in places   os.dup(%d) -> %ds   os.dup2(%d,%d)t   oldN(   t   debug_childR   R   R   R   R   R5   R   R$   t   keyst   sortR   t   _unsetCloseOnExect   dupR   t   dup2t   appendRv   (   R;   R   R   t   errfdt   destListR1   t	   childlistt   childR   t	   newtargett   ct   pR   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR     s\    		 

  
 
 c         C   s   |  j  | j |  d  S(   N(   R   R   (   R;   R   R@   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyt   writeToChild.  s    c         C   s'   | |  j  k r# |  j  | j   n  d  S(   N(   R   RX   (   R;   R   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyt   closeChildFD1  s    c         C   s:   x3 |  j  j   D]" } t | t  r | j   q q Wd  S(   N(   R   t
   itervaluest
   isinstanceRO   RC   (   R;   R   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyt   pauseProducing9  s    c         C   s:   x3 |  j  j   D]" } t | t  r | j   q q Wd  S(   N(   R   R   R   RO   R:   (   R;   R   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyt   resumeProducing>  s    c         C   s   |  j  d  d S(   sD   
        Call this to close standard input on this process.
        i    N(   R   (   R;   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyt
   closeStdinD  s    c         C   s   |  j  d  d  S(   Ni   (   R   (   R;   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyt   closeStdoutJ  s    c         C   s   |  j  d  d  S(   Ni   (   R   (   R;   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyt   closeStderrM  s    c         C   s"   |  j    |  j   |  j   d  S(   N(   R   R   R   (   R;   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyRX   P  s    

c         C   s*   d |  j  k r& |  j  d j |  n  d S(   s   
        Call this to write to standard input on this process.

        NOTE: This will silently lose data if there is no standard input.
        i    N(   R   R   (   R;   R@   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR   U  s    c         C   s7   d |  j  k r) |  j  d j | |  n
 | j   d S(   s   
        Call this to register producer for standard input.

        If there is no standard input producer.stopProducing() will
        be called immediately.
        i    N(   R   t   registerProducert   stopProducing(   R;   t   producert	   streaming(    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR   ^  s    c         C   s'   d |  j  k r# |  j  d j   n  d S(   s=   
        Call this to unregister producer for standard input.i    N(   R   t   unregisterProducer(   R;   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR   j  s    c         C   s*   d |  j  k r& |  j  d j |  n  d S(   s   
        Call this to write to standard input on this process.

        NOTE: This will silently lose data if there is no standard input.
        i    N(   R   t   writeSequence(   R;   t   seq(    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR   p  s    c         C   s   |  j  j | |  d  S(   N(   R   RT   (   R;   R0   R@   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyRT   z  s    c         C   sZ   t  j |  j | j    |  j | =y |  j j |  Wn t j   n X|  j   d  S(   N(	   R   R$   R   R5   R   RH   R   R   t   maybeCallProcessEnded(   R;   R   RI   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyRH   ~  s    
c         C   s5   |  j  r d  S|  j s$ |  j   d  St j |   d  S(   N(   R   t   lostProcessR   RY   R   (   R;   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR     s    		
N(    RJ   RK   RL   R    R
   R#   R   R   R   R   R   R+   R   RO   R   R-   R   R   R   R   R   R   R   R   RX   R   R   R   R   RT   RH   R   (    (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR   N  s2   
e	a													
		t
   PTYProcessc           B   s   e  Z d  Z e e  d Z d Z d d d d  Z d   Z	 d   Z
 d   Z d   Z d   Z d   Z d	   Z d
   Z d   Z RS(   s<   
    An operating-system Process that uses PTY support.
    ic
         C   s  t  d k r1 t |	 t t f  r1 t d   n  t j j |  |  t	 j |  |  t |	 t t f  r{ |	 \ }
 } } n! t  j
   \ }
 } t j |  } y, |  j | | | | | | d |
 d | Wn< t |	 t t f  s t j |
  t j |  n    n Xt j |  t j |
  |
 |  _ |  j   d |  _ d |  _ y |  j j |   Wn t j   n Xt |  j |   d S(   s  
        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.)
        s:   cannot use PTYProcess on platforms without the pty module.t   masterfdt   slavefdi   iN(   t   ptyR   R   t   tuplet   listR   R   R,   R-   RY   t   openptyR   t   ttynameR   R$   R   R.   R1   R:   RM   R   R   R   R   R   R   R   (   R;   R<   R   R   R   R   R   R   R   t   usePTYR   R   R   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR-     s8    "	
		c         C   se  t  j |  t t d  r y  t  j d t  j t  j B } Wn t k
 rO q Xy t j	 | t j
 d  Wn n Xt  j |  n  t  j   t t d  r t j	 | t j d  n  x0 t d  D]" } | | k r t  j |  q q Wt  j | d  t  j | d  t  j | d  x; t   D]0 } | d k r#y t  j |  WqSqSXq#q#W|  j   d	 S(
   sE   
        Setup child process after fork() but before exec().
        t	   TIOCNOTTYs   /dev/ttyRP   t	   TIOCSCTTYi   i    i   i   N(   R   R$   t   hasattrt   termiosR   t   O_RDWRt   O_NOCTTYR9   t   fcntlt   ioctlR   t   setsidR   Rp   R   R   Rv   (   R;   R   R   R1   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR     s6     
c         C   s   d  S(   N(    (   R;   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR     s    c         C   s   d  S(   N(    (   R;   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR     s    c         C   s   d  S(   N(    (   R;   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR     s    c            s   t  j   j   f d    S(   sM   
        Called when my standard output stream is ready for reading.
        c            s     j  j d |   S(   Ni   (   R   RT   (   R@   (   R;   (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyt   <lambda>  s    (   R   RR   R1   (   R;   (    (   R;   s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyRE     s    c         C   s   |  j  S(   sR   
        This returns the file number of standard output on this process.
        (   R1   (   R;   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR5     s    c         C   s#   |  j  d k r t j |   n  d  S(   Ni   (   R   RY   R   (   R;   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR     s    c         C   s@   t  j j |  |  t j |  j  |  j d 7_ |  j   d S(   sU   
        I call this to clean up when one or all of my connections has died.
        i   N(   R   R,   RG   R   R$   R1   R   R   (   R;   RI   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyRG     s    c         C   s   t  j |  j |  S(   s6   
        Write some data to the open process.
        (   R   R>   R1   (   R;   R@   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyRB   &  s    N(   RJ   RK   RL   R    R
   R   R   R   R-   R   R   R   R   RE   R5   R   RG   RB   (    (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyR     s   
0	*						
		(0   RL   R~   R   R   R2   R   R    Rk   RZ   R   t   ImportErrorR   R  R   t   zope.interfaceR    t   twisted.pythonR   R   t   twisted.python.utilR   t   twisted.internetR   R   R   t   twisted.internet.mainR   R   t   twisted.internet._baseprocessR	   t   twisted.internet.interfacesR
   Rl   R   R   R   R   R*   R,   R+   RO   t   objectRY   R   R   R   R   R   (    (    (    s<   /usr/lib/python2.7/dist-packages/twisted/internet/process.pyt   <module>   s@   `

					r:n		 K