
    q&f|                     
   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mZmZm	Z	m
Z
 	 ddlmZ ej                   ej                  dk(  r9d dlZd dlZej$                  ZdZdZdZd	Z ej.                  d
      j0                  ZdZdZdZdZdZd ZdZ dZ!dZ"ej$                  jF                  Z$ G d dejJ                        Z& ejN                  ejP                        Z)ejT                  jV                  Z,e,jZ                  Z.ej^                  ejP                  ejP                  ej`                  ejP                  ejP                  ejb                  ge._2        ejb                  e._3        e,jh                  Z4ejb                  ge4_2        ejj                  e4_3        e,jl                  Z6ejb                  ej`                  ejP                  e) ejN                  e&      ge6_2        ejj                  e6_3        e,jn                  Z7ejb                  ej`                  ejP                  e) ejN                  e&      ge7_2        ejj                  e7_3        e,jp                  Z8g e8_2        ejP                  e8_3        e,jr                  Z9ejP                  ge9_2        de9_3        e,jt                  Z;ejP                  ej`                  ejP                  ejP                   ejN                  ej^                        ejP                  ej`                  ge;_2        ejP                  e;_3        e,jx                  Z<e,jz                  Z=ejb                   ejN                  e&      e)ejj                  ge=_2        ejj                  e=_3         e>e,dd      Z?e?Kejb                   ejN                  e&      e)ejP                  ejj                  ge?_2        ejj                  e?_3        e,j                  Z@ejb                  ejP                  ejj                  ge@_2        ejP                  e@_3        e,j                  ZBe)ejj                  ejj                  ej^                  geB_2        ejb                  eB_3        e,j                  ZCejb                   ejN                  e&      geC_2        ejj                  eC_3        dZDdZEeErd ZFnd ZFd ZG G d deH      ZI G d deI      ZJ G d deI      ZK G d  d!eI      ZL G d" d#eI      ZM G d$ d%eI      ZN G d& d'eI      ZO G d( d)      ZP G d* d+      ZQ G d, d-eP      ZRd. ZS G d/ d0eP      ZTd@d1ZU G d2 d3eP      ZV G d4 d5eQ      ZW G d6 d7eW      ZX G d8 d9eW      ZY G d: d;eYeX      ZZ G d< d=eQ      Z[ G d> d?      Z\y# e$ r
 ddlmZ Y 3w xY w)A    N   )capabilitiescompatencodingload)bser)pybserntl        i   @         i   l    i     i  c                   p    e Zd Zdefdefdej
                  fdej
                  fdej                  fgZd Zy)
OVERLAPPEDInternalInternalHighOffset
OffsetHighhEventc                 J    d| _         d| _        d| _        d| _        d| _        y Nr   )r   r   r   r   r   selfs    E/usr/lib/python3/dist-packages/hgext/fsmonitor/pywatchman/__init__.py__init__zOVERLAPPED.__init__V   s&    DM !DDKDODK    N)	__name__
__module____qualname__	ULONG_PTRwintypesDWORDHANDLE_fields_r    r   r   r   r   M   sB    #Y'x~~&8>>*x'
	r   r   GetOverlappedResultEx   Fc           	      ~    t        dt        j                  dt        j                               d| |d d  z         y )N[z%a, %d %b %Y %H:%M:%Sz] )printtimestrftimegmtimefmtargss     r   logr2      s1     5t{{}Ed1g	
r   c                      y Nr&   r/   s     r   r2   r2          r   c           	          t        j                         }t        t        t        z  t
        z  d| d|dd       	 |j                  t        |       S # t        |       w xY w)z7expand a win32 error code into a human readable messageNr   )ctypesc_char_pFormatMessageFORMAT_MESSAGE_FROM_SYSTEMFORMAT_MESSAGE_ALLOCATE_BUFFERFORMAT_MESSAGE_IGNORE_INSERTSvalue	LocalFree)errbufs     r   _win32_strerrorrA      sZ     //
C"
(	)
'	( 			
yy#	#s   A Ac                        e Zd ZddZd Zd Zy)WatchmanErrorNc                      || _         || _        y r4   )msgcmd)r   rE   rF   s      r   r   zWatchmanError.__init__   s    r   c                     || _         y r4   )rF   )r   rF   s     r   
setCommandzWatchmanError.setCommand   s	    r   c                 h    | j                   r| j                  d| j                   S | j                  S )Nz, while executing )rF   rE   r   s    r   __str__zWatchmanError.__str__   s%    88/3xxBBxxr   NN)r   r   r    r   rH   rJ   r&   r   r   rC   rC      s    r   rC   c                       e Zd Zy)BSERv1UnsupportedNr   r   r    r&   r   r   rM   rM          r   rM   c                       e Zd Zy)UseAfterForkNrN   r&   r   r   rQ   rQ     rO   r   rQ   c                         e Zd Zd fd	Z xZS )WatchmanEnvironmentErrorc                 P    t         t        |   dj                  |||      |       y )Nz{0}: errno={1} errmsg={2})superrS   r   format)r   rE   errnoerrmsgrF   	__class__s        r   r   z!WatchmanEnvironmentError.__init__	  s'    &6'..sE6BC	
r   r4   r   r   r    r   __classcell__rY   s   @r   rS   rS     s    
 
r   rS   c                        e Zd Z fdZ xZS )SocketConnectErrorc                 T    t         t        |   d|d|       || _        || _        y )Nzunable to connect to z: )rU   r^   r   sockpathexc)r   r`   ra   rY   s      r   r   zSocketConnectError.__init__  s+     $0-5s;	
 !r   rZ   r\   s   @r   r^   r^     s     r   r^   c                       e Zd ZdZy)SocketTimeouta  A specialized exception raised for socket timeouts during communication to/from watchman.
    This makes it easier to implement non-blocking loops as callers can easily distinguish
    between a routine timeout and an actual error condition.

    Note that catching WatchmanError will also catch this as it is a super-class, so backwards
    compatibility in exception handling is preserved.
    Nr   r   r    __doc__r&   r   r   rc   rc     s    r   rc   c                   $     e Zd ZdZd fd	Z xZS )CommandErrorzRerror returned by watchman

    self.msg is the message returned by watchman.
    c                 4    t         t        |   d||       y )Nzwatchman command error: )rU   rg   r   )r   rE   rF   rY   s      r   r   zCommandError.__init__(  s    lD*,/13	
r   r4   )r   r   r    re   r   r[   r\   s   @r   rg   rg   "  s    

 
r   rg   c                   2    e Zd ZdZdZd Zd Zd Zd Zd Z	y)	Transportz.communication transport to the watchman serverNc                     t               )ztear it downNotImplementedErrorr   s    r   closezTransport.close3      !##r   c                     t               )zread size bytesrl   )r   sizes     r   	readByteszTransport.readBytes7  ro   r   c                     t               )zwrite some datarl   )r   r@   s     r   writezTransport.write;  ro   r   c                      y r4   r&   r   r=   s     r   
setTimeoutzTransport.setTimeout?  r5   r   c                    | j                   g | _         t        | j                         dk(  r=d| j                   d   v r,| j                   d   j                  dd      \  }}|g| _         |S 	 | j                  d      }d|v r=dj	                  | j                         }|j                  dd      \  }}|g| _         ||z   S | j                   j                  |       n)zread a line
        Maintains its own buffer, callers of the transport should not mix
        calls to readBytes and readLine.
        r      
r   r   r   )r@   lensplitrr   joinappend)r   linebresults       r   readLinezTransport.readLineB  s    
 88DH txx=A%488A;"6))%3IT1sDHKt$Az$((+GGE1-	q3}$HHOOA r   )
r   r   r    re   r@   rn   rr   rt   rw   r   r&   r   r   rj   rj   .  s#    8
C$$$r   rj   c                   ,    e Zd ZdZdZd Zd Zd Zd Zy)Codecz.communication encoding for the watchman serverNc                     || _         y r4   )	transport)r   r   s     r   r   zCodec.__init__`  s	    "r   c                     t               r4   rl   r   s    r   receivezCodec.receivec      !##r   c                     t               r4   rl   r   r1   s     r   sendz
Codec.sendf  r   r   c                 :    | j                   j                  |       y r4   )r   rw   rv   s     r   rw   zCodec.setTimeouti  s    !!%(r   )	r   r   r    re   r   r   r   r   rw   r&   r   r   r   r   [  s    8I#$$)r   r   c                   2    e Zd ZdZdZd Zd Zd Zd Zd Z	y)UnixSocketTransportz"local unix domain socket transportNc                    || _         || _        t        j                  t        j                  t        j                        }	 |j                  | j                         |j                  | j                          || _        y # t        j                  $ r+}|j                          t        | j                   |      d }~ww xY wr4   )r`   timeoutsocketAF_UNIXSOCK_STREAM
settimeoutconnectsockerrorrn   r^   )r   r`   r   r   es        r   r   zUnixSocketTransport.__init__r  s     }}V^^V-?-?@	7OODLL)LL'DI|| 	7JJL$T]]A66	7s   =B   B>&B99B>c                 `    | j                   r"| j                   j                          d | _         y y r4   )r   rn   r   s    r   rn   zUnixSocketTransport.close  s#    99IIOODI r   c                 \    || _         | j                  j                  | j                          y r4   )r   r   r   rv   s     r   rw   zUnixSocketTransport.setTimeout  s    		T\\*r   c                     	 | j                   j                  |      g}|d   st        d      |d   S # t        j                  $ r t        d      w xY w)Nr   empty watchman responseztimed out waiting for response)r   recvrC   r   r   rc   )r   rq   r@   s      r   rr   zUnixSocketTransport.readBytes  sZ    	B99>>$'(Cq6#$=>>q6M~~ 	B @AA	Bs	   03 Ac                     	 | j                   j                  |       y # t        j                  $ r t	        d      w xY w)Nztimed out sending query command)r   sendallr   r   rc   )r   datas     r   rt   zUnixSocketTransport.write  s;    	CIId#~~ 	C ABB	Cs    =)
r   r   r    re   r   r   rn   rw   rr   rt   r&   r   r   r   r   m  s%    ,D7
+BCr   r   c                 x   t        d|       |dk7  rt        |j                  ||      }|t        k(  rn{|t        k(  rt        t               nb|t        k(  rt        t               y|t        k(  r t               }t        dt        |             yt               }t        dt        |             yt        | ||d      S )a  Windows 7 and earlier does not support GetOverlappedResultEx. The
    alternative is to use GetOverlappedResult and wait for read or write
    operation to complete. This is done be using CreateEvent and
    WaitForSingleObjectEx. CreateEvent, WaitForSingleObjectEx
    and GetOverlappedResult are all part of Windows API since WindowsXP.
    This is the exact same implementation that can be found in the watchman
    source code (see get_overlapped_result_ex_impl in stream_win.c). This
    way, maintenance should be simplified.
    z"Preparing to wait for maximum %dmsr   Fz WaitForSingleObjectEx failed: %szUnexpected error: %s)r2   WaitForSingleObjectExr   WAIT_OBJECT_0WAIT_IO_COMPLETIONSetLastErrorWAIT_TIMEOUTWAIT_FAILEDGetLastErrorrA   GetOverlappedResult)pipeolapnbytesmillis	alertablewaitReturnCoder?   s          r   _get_overlapped_result_ex_implr     s     ,f5{.t{{FIN]*11 +,|+ &{*.C2OC4HI .C&(<=tT6599r   c                   :    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
y	)
WindowsNamedPipeTransportzconnect to a named pipec           	         || _         t        t        j                  |dz              | _        d | _        t        j                  rt        j                  |      }t        |t        t        z  dd t        t        d       | _        t!               }| j                  t"        k(  s| j                  dk(  r-d | _        t%        | j                   | j'                  d|            t)        d ddd       | _        t!               }| j*                  | j-                  d|       t.        | _        t        j2                  d      dk(  s| j0                  t4        | _        y y )	N  r    TFzCreateEvent failedWATCHMAN_WIN7_COMPAT1)r`   intmathceilr   _iobufr   PYTHON3osfsencode
CreateFileGENERIC_READGENERIC_WRITEOPEN_EXISTINGFILE_FLAG_OVERLAPPEDr   r   INVALID_HANDLE_VALUEr^   _make_win_errCreateEvent	_waitable_raise_win_errr'   _get_overlapped_result_exgetenvr   )r   r`   r   r?   s       r   r   z"WindowsNamedPipeTransport.__init__  s    499Wt^45>>{{8,H=( 
	 n99,,		QDI$T]]D4F4Fr34OPP %T4=n>>! 4c:)>&II,-4--5-KD* 6r   c                 &    | j                  ||      r4   )r   r   rE   r?   s      r   r   z(WindowsNamedPipeTransport._raise_win_err  s      c**r   c                 6    t        d||t        |      fz        S )Nz%s win32 error code: %d %s)IOErrorrA   r   s      r   r   z'WindowsNamedPipeTransport._make_win_err  s#    (Coc6J+KK
 	
r   c                     | j                   r t        d       t        | j                          d | _         | j                  t        | j                         d | _        y )NzClosing pipe)r   r2   CloseHandler   r   s    r   rn   zWindowsNamedPipeTransport.close  sA    99		"	>>%'r   c                 *    t        |dz        | _        y )Nr   )r   r   rv   s     r   rw   z$WindowsNamedPipeTransport.setTimeout  s    54<(r   c                    | j                   rR|t        | j                         k\  r| j                   }d| _        |S | j                   d| }| j                   |d | _         |S t        j                  |      }t               }| j                  |_        t        d|       t        | j                  ||d|      }|s(t               }|t        k7  r| j                  d|z  |       t        j                         }| j!                  | j                  |||rdn| j"                  d      sjt               }t%        | j                  |       |t&        k(  r#t        d       t)        d| j"                  z        t        d|       | j                  d	|       |j*                  }|dk(  r!t%        | j                  |       t-        d
      |d| }t/        ||      }||k(  r|S ||d | _         |d| S )zA read can block for an unbounded amount of time, even if the
        kernel reports that the pipe handle is signalled, so we need to
        always perform our reads asynchronously
        Nzmade read buff of size %dzfailed to read %d bytesr   TzGetOverlappedResultEx timedoutz%timed out after waiting %dms for readz&GetOverlappedResultEx reports error %dzerror while waiting for readz'Async read yielded 0 bytes; unpossible!)r   rz   r@   r7   create_string_bufferr   r   r   r2   ReadFiler   r   ERROR_IO_PENDINGr   r"   r#   r   r   
CancelIoExr   rc   r=   r   min)	r   rq   resr@   r   	immediater?   nreadreturned_sizes	            r   rr   z#WindowsNamedPipeTransport.readBytes  s    ;;s4;;''kk
++et$C++de,DKJ ))$/|nn'. TYYT4>	.C&&##$=$DcJ --IItUAd
 .Ctyy$'l"45#;dllJ  8#> >DA:
 tyy$'CDD &5kE4(E!J -.)>M""r   c                    t               }| j                  |_        t        | j                  t        j                  |      t        |      d |      }|s=t               }|t        k7  r*| j                  dt        |      | j                  fz  |       t        j                         }| j                  | j                  |||rdn| j                  d      r"t        d|j                          |j                   S t               }t#        | j                  |       |t$        k(  rt'        d| j                  z        | j                  dt        |      z  |       y )Nz%failed to write %d bytes to handle %rr   Tzmade write of %d bytesz&timed out after waiting %dms for writez)error while waiting for write of %d bytes)r   r   r   	WriteFiler   r7   r8   rz   r   r   r   r"   r#   r   r   r2   r=   r   r   rc   )r   r   r   r   r?   nwrotes         r   rt   zWindowsNamedPipeTransport.writeA  s   |nnIIvt,c$it
	 .C&&##;4y$)),- !))IItV)Qt
 (&,,7<<n 	499d#,84<<G  	7#d)CS	
r   N)r   r   r    re   r   r   r   rn   rw   rr   rt   r&   r   r   r   r     s,    !!LF+

	)B#H%
r   r   c                 J    | r| S t         j                  j                  dd      S )NWATCHMAN_BINARYwatchman)r   environget)binpaths    r   _default_binpathr   i  s"     ::>>+Z88r   c                   8    e Zd ZdZdZdZd	dZd Zd Zd Z	d Z
y)
CLIProcessTransporta"  open a pipe to the cli to talk to the service
    This intended to be used only in the test harness!

    The CLI is an oddball because we only support JSON input
    and cannot send multiple commands through the same instance,
    so we spawn a new process for each command.

    We disable server spawning for this implementation, again, because
    it is intended to be used only in our test harness.  You really
    should not need to use the CLI transport for anything real.

    While the CLI can output in BSER, our Transport interface doesn't
    support telling this instance that it should do so.  That effectively
    limits this implementation to JSON input and output only at this time.

    It is the responsibility of the caller to set the send and
    receive codecs appropriately.
    NTc                 @    || _         || _        t        |      | _        y r4   )r`   r   r   r   )r   r`   r   r   s       r   r   zCLIProcessTransport.__init__  s     '0r   c                 P   | j                   r| j                   j                  | j                   j                          | j                   j                  j	                          | j                   j
                  j	                          | j                   j                          d | _         y y r4   )procpidkillstdinrn   stdoutwaitr   s    r   rn   zCLIProcessTransport.close  si    99yy}}(		 IIOO!!#II""$IINNDI r   c                    | j                   r| j                   S | j                  dj                  | j                        ddddddg}t	        j
                  |t        j                  t        j                        | _         | j                   S )	Nz--sockname={0}z--logfile=/BOGUSz--statefile=/BOGUSz
--no-spawnz
--no-localz--no-prettyz-j)r   r   )r   r   rV   r`   
subprocessPopenPIPEr   s     r   _connectzCLIProcessTransport._connect  st    9999LL##DMM2 	
 $$


	 yyr   c                     | j                          | j                  j                  j                  |      }|st	        d      |S )NzEOF on CLI process transport)r   r   r   readrC   )r   rq   r   s      r   rr   zCLIProcessTransport.readBytes  s9    ii##D) >??
r   c                     | j                   r| j                          d| _         | j                         }|j                  j	                  |      }|j                  j                          d| _         |S )NFT)closedrn   r   r   rt   )r   r   r   r   s       r   rt   zCLIProcessTransport.write  sT    ;;JJLDK}}jjt$


r   r4   )r   r   r    re   r   r   r   rn   r   rr   rt   r&   r   r   r   r   r  s,    & DF1
$r   r   c                   4     e Zd ZdZ fdZd Zd Zd Z xZS )	BserCodecz<use the BSER encoding.  This is the default, preferred codecc                 H    t         t        |   |       || _        || _        y r4   )rU   r   r   _value_encoding_value_errors)r   r   value_encodingvalue_errorsrY   s       r   r   zBserCodec.__init__  s"    i'	2-)r   c                 Z    t        j                  || j                  | j                        S )Nr   r   r   loadsr   r   r   responses     r   _loadszBserCodec._loads  s(    zz//++
 	
r   c                    | j                   j                  t              g}|d   st        d      t	        j
                  |d         \  }}}t        |d         }||kD  rD|j                  | j                   j                  ||z
               |t        |d         z  }||kD  rDdj                  |      }	 | j                  |      }|S # t        $ r}t        d|z        d }~ww xY w)Nr   r   r   r   "watchman response decode error: %s)r   rr   	sniff_lenrC   r   pdu_inforz   r}   r|   r  
ValueError)	r   r@   _1_2elenrlenr  r   r   s	            r   r   zBserCodec.receive  s    ~~''	231v 9::}}SV,B3q6{TkJJt~~//t<=CBL D Tk 88C=	J++h'CJ 	J Dq HII	Js   6C	 		C%C  C%c                 ^    t        j                  | }| j                  j                  |       y r4   )r   dumpsr   rt   r   r1   rF   s      r   r   zBserCodec.send  s"    jj$S!r   )	r   r   r    re   r   r  r   r   r[   r\   s   @r   r   r     s    F*

J&"r   r   c                       e Zd ZdZd Zy)ImmutableBserCodecSuse the BSER encoding, decoding values using the newer
    immutable object supportc                 \    t        j                  |d| j                  | j                        S )NFr  r  r  s     r   r  zImmutableBserCodec._loads  s+    zz//++	
 	
r   N)r   r   r    re   r  r&   r   r   r  r    s     
r   r  c                   .     e Zd ZdZ fdZd Zd Z xZS )Bser2WithFallbackCodeczuse BSER v2 encodingc                    t         t        |   |||       t        j                  rd}nd}| j                  d|dgig       | j                         }d|v rt        d      |d   d   rd| _        d	| _	        y d
| _        d	| _	        y )Nrequiredoptionalversionzbser-v2r   z[The watchman server version does not support Python 3. Please upgrade your watchman server.r      r   r   )
rU   r  r   r   r   r   r   rM   bser_versionbser_capabilities)r   r   r   r   
bserv2_keyr   rY   s         r   r   zBser2WithFallbackCodec.__init__  s    $d4~|	
 >>#J#J		9zI;789||~l"#0 
 '	2 !D%&D" !D%&D"r   c                 F   | j                   j                  t              g}|d   st        d      t	        j
                  |d         \  }}}t        | d      r/t        | j                  |      | _        | j                  |z  | _
        t        |d         }||kD  rD|j                  | j                   j                  ||z
               |t        |d         z  }||kD  rDdj                  |      }	 | j                  |      }|S # t        $ r}t        d|z        d }~ww xY w)Nr   r   r  r   r   r  )r   rr   r	  rC   r   r
  hasattrmaxr  r  r   rz   r}   r|   r  r  )	r   r@   recv_bser_versionrecv_bser_capabilitiesr  r  r  r   r   s	            r   r   zBser2WithFallbackCodec.receive  s   ~~''	231v 9:::>--A:O7144( #D$5$57H ID $ 6 69O OD3q6{TkJJt~~//t<=CBL D Tk 88C=	J++h'CJ 	J Dq HII	Js   1D 	D DD c                     t        | d      r+t        j                  || j                  | j                  d}nt        j                  | }| j
                  j                  |       y )Nr  )r  r   )r"  r   r  r  r  r   rt   r  s      r   r   zBser2WithFallbackCodec.send$  sQ    4(**))!33C **d#CS!r   )r   r   r    re   r   r   r   r[   r\   s   @r   r  r    s    '4J0	"r   r  c                       e Zd ZdZy)ImmutableBser2Codecr  Nrd   r&   r   r   r(  r(  0  s      	r   r(  c                   2     e Zd ZdZdZ fdZd Zd Z xZS )	JsonCodecz<Use json codec.  This is here primarily for testing purposesNc                 B    t         t        |   |       dd l}|| _        y r   )rU   r*  r   json)r   r   r,  rY   s      r   r   zJsonCodec.__init__<  s    i'	2	r   c                     | j                   j                         }	 t        j                  r|j	                  d      }| j
                  j                  |      S # t        $ r}t        ||        d }~ww xY w)Nzutf-8)	r   r   r   r   decoder,  r  	Exceptionr+   )r   r~   r   s      r   r   zJsonCodec.receiveC  s_    ~~&&(	 ~~{{7+99??4(( 	!TN	s   ;A 	A3!A..A3c                      | j                   j                  | }t        j                  r|j	                  d      }| j
                  j                  |dz          y )Nasciiry   )r,  r  r   r   encoder   rt   r  s      r   r   zJsonCodec.sendR  sC    diioot$ >>**W%CS5[)r   )	r   r   r    re   r,  r   r   r   r[   r\   s   @r   r*  r*  7  s    FD*r   r*  c                       e Zd ZdZdZdZdZdZdZdZ	i Z
i Zg ZddgZdZdZdZ	 	 	 	 	 	 	 	 	 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dZddZd ZddZ d Z!y)clientz3Handles the communication with the watchman serviceNr2   subscriptionc
                 ~   || _         || _        || _        t        |	      | _        t        j                  |      rt        |t              r|| _	        ny|xs t        j                  d      xs d}|dk(  rt        j                  dk(  rt        | _	        n8|dk(  rt        | _	        n'|dk(  rt        | _	        |d}||}nt!        d|z        t#        |xs t        j                  d      xs d      }t#        |xs t        j                  d      xs d      }| j%                  |      | _        | j%                  |      | _        |d	u rNt*        j,                  r/t/        j0                         | _        t.        j4                  | _        y d | _        d | _        y || _        |d	u rt.        j4                  | _        y || _        y )
NWATCHMAN_TRANSPORTlocalr
   clir,  zinvalid transport %sWATCHMAN_ENCODINGr   F)r`   r   useImmutableBserr   r   inspectisclass
issubclassrj   r   r   r   namer   r   r   rC   str_parseEncoding	recvCodec	sendCodecr   r   r   get_local_encodingvalueEncodingdefault_local_errorsvalueErrors)
r   r`   r   r   sendEncodingrecvEncodingr;  rE  rG  r   s
             r   r   zclient.__init__m  s    ! 0'0??9%*Y	*J&DN!ORYY/C%DOIG#4!:g%!4e#!4'#)L'#/L#$:Y$FGGDBII&9:Df
 DBII&9:Df
 ,,\:,,\: E!~~%-%@%@%B"#+#@#@ %)"#' !.De##+#@#@ #. r   c                       fd}|S )Nc                 @     | j                   j                        S r4   )rE  rG  )r   codecr   s    r   
make_codecz)client._makeBSERCodec.<locals>.make_codec  s    D$6$68H8HIIr   r&   )r   rL  rM  s   `` r   _makeBSERCodeczclient._makeBSERCodec  s    	J r   c                 V   |dk(  r6| j                   r| j                  t              S | j                  t              S |dk(  rQt        j
                  rt        d      | j                   r| j                  t              S | j                  t              S |dk(  rt        S t        d|z        )Nr   zbser-v1zrPython 3 does not support the BSER v1 encoding: specify "bser" or omit the sendEncoding and recvEncoding argumentsr,  zinvalid encoding %s)r;  rN  r(  r  r   r   rM   r  r   r*  rC   )r   encs     r   rA  zclient._parseEncoding  s    &=$$**+>??&&'=>>I~~'  
 $$**+=>>&&y11F] 5 ;<<r   c                 :    | j                   rt        ||      S ||v S r4   )r;  r"  )r   r   r?  s      r   _haspropzclient._hasprop  s"      64((v~r   c                 r   t        j                  d      }|r|S | j                  ddg}	 t        t        j
                  t        j
                        }t         j                  dk(  r<t	        j                         }|xj                  t        j                  z  c_        ||d<   t	        j                  |fi |}|j                         \  }}|j                         }	|	rt        d|	z        t        j                   |      }
d	|
v rt        d
|
d	   z        |
d   S # t        $ r}t        d|z        d }~ww xY w)NWATCHMAN_SOCKz--output-encoding=bserzget-sockname)r   stderrr
   startupinfoz&"watchman" executable not in PATH (%s)zwatchman exited with code %dr   zget-sockname error: %ssockname)r   r   r   dictr   r   r?  STARTUPINFOdwFlagsSTARTF_USESHOWWINDOWr   OSErrorrC   communicatepollr   r  )r   pathrF   r1   rV  pr   r   rU  exitcoder   s              r   _resolvesocknamezclient._resolvesockname  s(    yy)K||5~F	N!zD ww$ )446##z'F'FF# '2]#  --A
 668 > IJJF#f 86'? JKKj!!  	N H1 LMM	Ns   BD 	D6#D11D6c                    | j                   r-| j                  t        j                         k7  rt	        d      y| j
                  | j                         | _        i }| j                  t        k(  r| j                  |d<    | j                  | j
                  | j                  fi || _        | j                  | j                        | _        | j                  | j                        | _         t        j                         | _        y)zestablish transport connectionz@do not re-use a connection after fork; open a new client insteadNr   )recvConnr   r   getpidrQ   r`   rb  r   r   r   r   tportrC  sendConnrB  )r   kwargss     r   r   zclient._connect  s     ==xx299;&"V  ==  113DM>>00 $F9 $T^^DMM4<<J6J
 tzz2tzz299;r   c                 $    | j                          y r4   rn   r   s    r   __del__zclient.__del__      

r   c                 &    | j                          | S r4   )r   r   s    r   	__enter__zclient.__enter__  s    r   c                 $    | j                          y r4   rj  )r   exc_type	exc_valueexc_tracebacks       r   __exit__zclient.__exit__  rl  r   c                 |    | j                   r0| j                   j                          d | _         d | _        d | _        y y r4   )rf  rn   rd  rg  r   s    r   rn   zclient.close  s3    ::JJDJ DM DM	 r   c                    | j                          | j                  j                         }| j                  |d      rt	        |d         | j                  |d      r| j
                  j                  |d          | j                  |d      r|d   }|| j                  vrg | j                  |<   | j                  |   j                  |       t        j                  j                  t        j                  j                  |d               }|| j                  vri | j                  |<   || j                  |   vrg | j                  |   |<   | j                  |   |   j                  |       |S )a  receive the next PDU from the watchman service

        If the client has activated subscriptions or logs then
        this PDU may be a unilateral PDU sent by the service to
        inform the client of a log event or subscription change.

        It may also simply be the response portion of a request
        initiated by query.

        There are clients in production that subscribe and call
        this in a loop to retrieve all subscription responses,
        so care should be taken when making changes here.
        r   r2   r5  root)r   rd  r   rR  rg   logsr}   subsr   r_  normpathnormcasesub_by_root)r   r   subrv  s       r   r   zclient.receive!  s9    	&&(==)vg//=='IIVE]+==0(C499$!#		#IIcN!!&) 77##BGG$4$4VF^$DED4+++)+  &$**400.0  &s+T"3'..v6r   c                 F    d|v r|d   ry| j                   D ]  }||v s y y)N
unilateralTF)r~  )r   r   ks      r   isUnilateralResponsezclient.isUnilateralResponseH  s6    33|#4 	ACx	 r   c                 0    | j                   }|rg | _         |S )zRetrieve buffered log data

        If remove is true the data will be removed from the buffer.
        Otherwise it will be left in the buffer
        )rw  )r   remover   s      r   getLogzclient.getLogQ  s     iiDI
r   c                    |t         j                  j                  t         j                  j                  |            }|| j                  vry|| j                  |   vry| j                  |   |   }|r+| j                  |   |= || j
                  v r| j
                  |= |S || j
                  vry| j
                  |   }|r| j
                  |= |S )a  Retrieve the data associated with a named subscription

        If remove is True (the default), the subscription data is removed
        from the buffer.  Otherwise the data is returned but left in
        the buffer.

        Returns None if there is no data associated with `name`

        If root is not None, then only return the subscription
        data that matches both root and name.  When used in this way,
        remove processing impacts both the unscoped and scoped stores
        for the subscription data.
        N)r   r_  ry  rz  r{  rx  )r   r?  r  rv  r|  s        r   getSubscriptionzclient.getSubscription\  s     77##BGG$4$4T$:;D4+++4++D11""4(.C$$T*40499$		$Jtyy iio		$
r   c                    t        d       | j                          	 | j                  j                  |       | j	                         }| j                  |      r"| j	                         }| j                  |      r"|S # t        $ r'}t        d|j                  |j                  |      d}~wt        $ r}|j                  |        d}~ww xY w)a?  Send a query to the watchman service and return the response

        This call will block until the response is returned.
        If any unilateral responses are sent by the service in between
        the request-response they will be buffered up in the client object
        and NOT returned via this method.
        zcalling client.queryz,I/O error communicating with watchman daemonN)r2   r   rg  r   r   r  EnvironmentErrorrS   rW   strerrorrC   rH   )r   r1   r   eeexs        r   queryzclient.query  s     	"#	MMt$,,.C++C0lln ++C0 J 	 +>	   	MM$	s*   AA= ;A= =	C"B((C4CCc                     | j                  d|xs g |xs g d      }| j                  |d      s(t        j                  ||       d|v rt	        |d         |S )z!Perform a server capability checkr  )r  r  r   r   )r  rR  r   
synthesizerg   )r   r  r  r   s       r   capabilityCheckzclient.capabilityCheck  s_    jjHNBO
 }}S.1 ##C2#~"3w<00
r   c                 p    | j                   j                  |       | j                  j                  |       y r4   )rd  rw   rg  rv   s     r   rw   zclient.setTimeout  s&      '  'r   )	Ng      ?NNNFFFN)T)TNrK   )"r   r   r    re   r`   r   rC  rB  rg  rd  rx  r{  rw  r~  rf  r;  r   r   rN  rA  rR  rb  r   rk  rn  rs  rn   r   r  r  r  r  r  rw   r&   r   r   r4  r4  \  s    =HIIIHHDKD(JE
C  >/@=(
("T4!%N	!F@(r   r4  r4   )]r<  r   r   r   r   r,   r   r   r   r   r   r   r
  ImportErrorr	   r?  r7   ctypes.wintypesr"   r   r   r   r   c_void_pr=   r   r:   r;   r<   r   r   r   r   INFINITEr   WPARAMr!   	Structurer   POINTERr#   LPDWORDwindllkernel32	_kernel32CreateFileAr   LPSTRLPVOIDr$   argtypesrestyper   BOOLr   r   r   r   FormatMessageAr9   r>   r   getattrr'   r   CreateEventAr   r   r	  
_debuggingr2   rA   r/  rC   rM   rQ   rS   r^   rc   rg   rj   r   r   r   r   r   r   r   r  r  r(  r*  r4  r&   r   r   <module>r     s  :   	    2 2
! 	MM
 77d?HLM%M*6??2.44!+%/"$.!KLM#H " &&IV%%   fnnX^^,G&&I&&JJ "J''K$OO,K"--K!!Hz"H  }}H##Iz"I !I))LL#>>L))L%^^,LL,,Mx~~&M %NNM##I#77z"	$  #+--#I/FM(OOFNN:&NNMM*
& )1%%;;&"
 %-NN!((K	K #//K %%J#??NFNN:,FGJ!J 	 

,I 	 		= 	
} 
 M 	
= 	
* *Z) )$(C) (CV%:Pf
	 f
R9F) FR$" $"N

 

>"Y >"B	02D 	"* "*JT( T([  !  !s   U U,+U,