
    "dM                    0   d dl m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mZm	Z	m
Z
 d dlmZ d dlmZ  ej                  d      Z eed      r eed      r	 eed      s ed	ej$                           ej&                  e	e	ee
d
      def      Z  ej&                  e	e	e
d
      def      Z  ej&                  e	d
      def      Z G d d      Z ed ej0                  ej2                  ej4                  ej6                  ej8                  ej:                  ej<                  ej>                  ej@                  ejB                  g
      Z" G d dejF                        Z$ ejJ                  e$      Z&dZ'e'e&dz   z  Z( G d d      Z) G d d      Z*y)    )annotationsN)c_char_pc_intc_uint32)reduce)UnsupportedLibcinotify_initinotify_add_watchinotify_rm_watchz Unsupported libc version found: T)	use_errnoc                      e 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eez  Ze	e
z  ZdZdZdZdZdZdZdZdZdZ ed eeeeeee	e
eeeeg      ZdZdZy)InotifyConstants                   @         i   i      i    i @  i   i   i   i   i    i   @l        c                    | |z  S N xys     >/usr/lib/python3/dist-packages/watchdog/observers/inotify_c.py<lambda>zInotifyConstants.<lambda>S   s
    QU     N)__name__
__module____qualname__	IN_ACCESS	IN_MODIFY	IN_ATTRIBIN_CLOSE_WRITEIN_CLOSE_NOWRITEIN_OPENIN_MOVED_FROMIN_MOVED_TO	IN_CREATE	IN_DELETEIN_DELETE_SELFIN_MOVE_SELFIN_CLOSEIN_MOVE
IN_UNMOUNTIN_Q_OVERFLOW
IN_IGNORED
IN_ONLYDIRIN_DONT_FOLLOWIN_EXCL_UNLINKIN_MASK_ADDIN_ISDIR
IN_ONESHOTr   IN_ALL_EVENTS
IN_CLOEXECIN_NONBLOCKr   r!   r   r   r   1   s    IIIN!GMKIINL  00Hk)G JMJ JNNKHJ 	
M& JKr!   r   c                    | |z  S r   r   r   s     r   r    r    k   s
    Q r!   c                  2    e Zd ZdZdefdefdefdefdefgZy)inotify_event_structa  
    Structure representation of the inotify_event structure
    (used in buffer size calculations)::

        struct inotify_event {
            __s32 wd;            /* watch descriptor */
            __u32 mask;          /* watch mask */
            __u32 cookie;        /* cookie to synchronize two events */
            __u32 len;           /* length (including nulls) of name */
            char  name[0];       /* stub for possible name */
        };
    wdmaskcookielennameN)r"   r#   r$   __doc__r   r   r   _fields_r   r!   r   rA   rA   {   s7     
u		8		Hr!   rA   r   r   c                      e Zd ZdZdefdZed        Zed        Zed        Z	ed        Z
d Zd	 Zd
 Zd Zd Zd ZefdZd Zd Zed        Zed        Zy)Inotifya	  
    Linux inotify(7) API wrapper class.

    :param path:
        The directory path for which we want an inotify object.
    :type path:
        :class:`bytes`
    :param recursive:
        ``True`` if subdirectories should be monitored; ``False`` otherwise.
    Fc                v   t               }|dk(  rt        j                          || _        t	        j
                         | _        i | _        i | _        || _	        || _
        || _        t        j                  j                  |      r| j                  |||       i | _        y | j!                  ||       i | _        y )N)r	   rJ   _raise_error_inotify_fd	threadingLock_lock_wd_for_path_path_for_wd_path_event_mask_is_recursiveospathisdir_add_dir_watch
_add_watch_moved_from_events)selfrX   	recursive
event_mask
inotify_fds        r   __init__zInotify.__init__   s    !^
  "%^^%
 
%&77==i< #% OOD*-"$r!   c                    | j                   S )z)The event mask for this inotify instance.)rU   r]   s    r   r_   zInotify.event_mask        r!   c                    | j                   S )z.The path associated with the inotify instance.)rT   rc   s    r   rX   zInotify.path   s     zzr!   c                    | j                   S )z0Whether we are watching directories recursively.)rV   rc   s    r   is_recursivezInotify.is_recursive   s     !!!r!   c                    | j                   S )z9The file descriptor associated with the inotify instance.)rN   rc   s    r   fdz
Inotify.fd   rd   r!   c                    i | _         y)z)Clear cached records of MOVED_FROM eventsN)r\   rc   s    r   clear_move_recordszInotify.clear_move_records   s
    "$r!   c                z    |j                   | j                  v r#| j                  |j                      j                  S y)z
        The source path corresponding to the given MOVED_TO event.

        If the source path is outside the monitored directories, None
        is returned instead.
        N)rD   r\   src_path)r]   destination_events     r   source_for_movezInotify.source_for_move   s9     ##t'>'>>**+<+C+CDMMMr!   c                6    || j                   |j                  <   y)zf
        Save this event as the source event for future MOVED_TO events to
        reference.
        N)r\   rD   )r]   events     r   remember_move_from_eventz Inotify.remember_move_from_event   s    
 16-r!   c                ~    | j                   5  | j                  || j                         ddd       y# 1 sw Y   yxY w)zn
        Adds a watch for the given path.

        :param path:
            Path to begin monitoring.
        N)rQ   r[   rU   )r]   rX   s     r   	add_watchzInotify.add_watch   s4     ZZ 	4OOD$"2"23	4 	4 	4s   3<c                    | j                   5  | j                  j                  |      }| j                  |= t	        | j
                  |      dk(  rt        j                          ddd       y# 1 sw Y   yxY w)z
        Removes a watch for the given path.

        :param path:
            Path string for which the watch will be removed.
        rL   N)rQ   rR   poprS   r   rN   rJ   rM   )r]   rX   rB   s      r   remove_watchzInotify.remove_watch   se     ZZ 	'""&&t,B!!"% 0 0"5;$$&		' 	' 	's   AA,,A5c                2   | j                   5  | j                  | j                  v r/| j                  | j                     }t        | j                  |       	 t        j                  | j                         ddd       y# t        $ r Y w xY w# 1 sw Y   yxY w)zQ
        Closes the inotify instance and removes all associated watches.
        N)rQ   rT   rR   r   rN   rW   closeOSError)r]   rB   s     r   ry   zInotify.close   s     ZZ 		zzT...&&tzz2 !1!126))*		 		  		 		s*   ABA>>	B
B	B

BBc           	          fd}d}	 	 t        j                   j                  |      }	  j                  5  g }t        j                  |      D ]  \  }}}}	|dk(  r j                  |   }
|	r t         j                  j                  |
|	      n|
}t        ||||	|      }|j                  r j                  |       nv|j                   ri j#                  |      }| j$                  v r j$                  |   } j$                  |= | j$                  |j&                  <   |j&                   j                  |<    j(                  r j$                  j+                         j-                         D ]  \  }}|j/                  |t         j                  j0                  j3                         z         sA j$                  j5                  |      }|j7                  ||j&                        }| j$                  |<   | j                  |<    t         j                  j                  |
|	      }t        ||||	|      }|j8                  r: j                  j5                  |      } j$                  |   |k(  r j$                  |= |j;                  |        j(                  sK|j<                  sY|j>                  sg	  jA                  | jB                         |jE                   ||              	 ddd       |S # t        $ rM}|j                  t        j
                  k(  rY d}~|j                  t        j                  k(  rg cY d}~S  d}~ww xY w# t        $ r Y w xY w# 1 sw Y   S xY w)z<
        Reads events from inotify and yields them.
        c           	     t   g }t        j                  |       D ]  \  }}}|D ]~  }	 t         j                  j                  ||      }j	                  |j
                        }t        |t        j                  t        j                  z  d||      }|j                  |        |D ]|  }	t         j                  j                  ||	      }j                  t         j                  j                  |         }
t        |
t        j                  d|	|      }|j                  |       ~  |S # t        $ r Y w xY wNr   )rW   walkrX   joinr[   rU   InotifyEventr   r-   r:   appendrz   rR   dirname)rm   eventsrootdirnames	filenamesr   	full_pathwd_direfilenamewd_parent_dirr]   s              r   _recursive_simulatez0Inotify.read_events.<locals>._recursive_simulate  s(   F-/WWX-> %)h	' G$&GGLLw$?	!%D<L<L!M(",669I9R9RR#% a( !* 
%H "T8 <I$($5$5bggooi6P$QM$%(22 !A MM!$
%%4 M # s   A;D**	D76D7NrL   )#rW   readrN   rz   errnoEINTREBADFrQ   rJ   _parse_event_bufferrS   rX   r   r   is_moved_fromrr   is_moved_toro   rR   rm   rg   copyitems
startswithsepencoderv   replace
is_ignoredr   is_directory	is_creater[   rU   extend)r]   event_buffer_sizer   event_bufferr   
event_listrB   rC   rD   rF   wd_pathrm   inotify_eventmove_src_pathmoved_wdrT   _wd_move_to_pathrX   s   `                  r   read_eventszInotify.read_events	  s"   	< !wwt'7'79JK ZZ ;	EJ*1*E*El*S 9E&D&$8++B/37BGGLL$/W  !-RvtX N ..11-@"..$($8$8$GM$(9(99#'#4#4]#C --m<DL))-*@*@A6C6L6L))(3,,.2.?.?.D.D.F.L.L.N 	P
s#(#3#3$1BGGKK4F4F4H$H$" 04/@/@/D/DU/KH49MM(5}7M7M5&M HPD$5$5m$DBOD$5$5h$?	P  "ww||GT:H$0T64$RM ++,,004D((."4 --d3!!-0 %%%22%//!$2B2BC %%&9(&CDs9E;	Ez M  77ekk)WW+IB # ! !q;	Ez sl    K9 E7M"0C)M"M")M"8MM"9	MM
%M
M	M

M	MM"MM""M,c                   t         j                  j                  |      s<t        t        j
                  t        j                  t        j
                        |      | j                  ||       |rxt        j                  |      D ]_  \  }}}|D ]T  }t         j                  j                  ||      }t         j                  j                  |      rC| j                  ||       V a yy)a/  
        Adds a watch (optionally recursively) for the given directory path
        to monitor events specified by the mask.

        :param path:
            Path to monitor
        :param recursive:
            ``True`` to monitor recursively.
        :param mask:
            Event bit mask.
        N)rW   rX   rY   rz   r   ENOTDIRstrerrorr[   r~   r   islink)	r]   rX   r^   rC   r   r   _r   r   s	            r   rZ   zInotify._add_dir_watch}  s     ww}}T"%--U]])CTJJd#%'WWT] 5!h' 5G "T7 ;Iww~~i0 OOIt4	55 r!   c                    t        | j                  ||      }|dk(  rt        j                          || j                  |<   || j
                  |<   |S )z
        Adds a watch for the given path to monitor events specified by the
        mask.

        :param path:
            Path to monitor
        :param mask:
            Event bit mask.
        rL   )r
   rN   rJ   rM   rR   rS   )r]   rX   rC   rB   s       r   r[   zInotify._add_watch  sP     t//t<8  ""$$ $"	r!   c                 D   t        j                         } | t        j                  k(  rt	        t        j                  d      | t        j
                  k(  rt	        t        j
                  d      | t        j                  k7  rt	        | t        j                  |             y)z5
        Raises errors for inotify failures.
        zinotify watch limit reachedzinotify instance limit reachedN)	ctypes	get_errnor   ENOSPCrz   EMFILEEACCESrW   r   )errs    r   rM   zInotify._raise_error  su    
  %,,%,,(EFFELL %,,(HIIELL #r{{3/00 !r!   c              #     K   d}|dz   t        |       k  r\t        j                  d| |      \  }}}}| |dz   |dz   |z    j                  d      }|d|z   z  }||||f |dz   t        |       k  r[yyw)a  
        Parses an event buffer of ``inotify_event`` structs returned by
        inotify::

            struct inotify_event {
                __s32 wd;            /* watch descriptor */
                __u32 mask;          /* watch mask */
                __u32 cookie;        /* cookie to synchronize two events */
                __u32 len;           /* length (including nulls) of name */
                char  name[0];       /* stub for possible name */
            };

        The ``cookie`` member of this struct is used to pair two related
        events, for example, it pairs an IN_MOVED_FROM event with an
        IN_MOVED_TO event.
        r   r   iIII    N)rE   structunpack_fromrstrip)r   irB   rC   rD   lengthrF   s          r   r   zInotify._parse_event_buffer  s     $ "fL))'-'9'9&,PQ'R$BffBR&9@@GDfAdFD((	 "fL))s   A.A31A3N)r"   r#   r$   rG   WATCHDOG_ALL_EVENTSra   propertyr_   rX   rg   ri   rk   ro   rr   rt   rw   ry   DEFAULT_EVENT_BUFFER_SIZEr   rZ   r[   staticmethodrM   r   r   r!   r   rJ   rJ      s    	 (-9L %*       " "    %
64' -F qh5." 
1 
1 ) )r!   rJ   c                     e Zd ZdZd Zed        Zed        Zed        Zed        Z	ed        Z
ed        Zed	        Zed
        Zed        Zed        Zed        Zed        Zed        Zed        Zed        Zed        Zed        Zed        Zed        Zed        Zed        Zd Zd Zd Zed        Zd Z y)r   a  
    Inotify event struct wrapper.

    :param wd:
        Watch descriptor
    :param mask:
        Event mask
    :param cookie:
        Event cookie
    :param name:
        Base name of the event source path.
    :param src_path:
        Full event source path.
    c                J    || _         || _        || _        || _        || _        y r   )r   _mask_cookie_name	_src_path)r]   rB   rC   rD   rF   rm   s         r   ra   zInotifyEvent.__init__  s%    

!r!   c                    | j                   S r   )r   rc   s    r   rm   zInotifyEvent.src_path  s    ~~r!   c                    | j                   S r   )r   rc   s    r   rB   zInotifyEvent.wd  s    xxr!   c                    | j                   S r   )r   rc   s    r   rC   zInotifyEvent.mask      zzr!   c                    | j                   S r   )r   rc   s    r   rD   zInotifyEvent.cookie  s    ||r!   c                    | j                   S r   )r   rc   s    r   rF   zInotifyEvent.name  r   r!   c                B    | j                   t        j                  z  dkD  S r}   )r   r   r&   rc   s    r   	is_modifyzInotifyEvent.is_modify      zz,666::r!   c                B    | j                   t        j                  z  dkD  S r}   )r   r   r(   rc   s    r   is_close_writezInotifyEvent.is_close_write      zz,;;;a??r!   c                B    | j                   t        j                  z  dkD  S r}   )r   r   r)   rc   s    r   is_close_nowritezInotifyEvent.is_close_nowrite  s    zz,===AAr!   c                B    | j                   t        j                  z  dkD  S r}   )r   r   r*   rc   s    r   is_openzInotifyEvent.is_open      zz,444q88r!   c                B    | j                   t        j                  z  dkD  S r}   )r   r   r%   rc   s    r   	is_accesszInotifyEvent.is_access  r   r!   c                B    | j                   t        j                  z  dkD  S r}   )r   r   r.   rc   s    r   	is_deletezInotifyEvent.is_delete  r   r!   c                B    | j                   t        j                  z  dkD  S r}   )r   r   r/   rc   s    r   is_delete_selfzInotifyEvent.is_delete_self  r   r!   c                B    | j                   t        j                  z  dkD  S r}   )r   r   r-   rc   s    r   r   zInotifyEvent.is_create  r   r!   c                B    | j                   t        j                  z  dkD  S r}   )r   r   r+   rc   s    r   r   zInotifyEvent.is_moved_from  s    zz,:::Q>>r!   c                B    | j                   t        j                  z  dkD  S r}   )r   r   r,   rc   s    r   r   zInotifyEvent.is_moved_to  s    zz,8881<<r!   c                B    | j                   t        j                  z  dkD  S r}   )r   r   r2   rc   s    r   is_movezInotifyEvent.is_move  r   r!   c                B    | j                   t        j                  z  dkD  S r}   )r   r   r0   rc   s    r   is_move_selfzInotifyEvent.is_move_self#  s    zz,999A==r!   c                B    | j                   t        j                  z  dkD  S r}   )r   r   r'   rc   s    r   	is_attribzInotifyEvent.is_attrib'  r   r!   c                B    | j                   t        j                  z  dkD  S r}   )r   r   r5   rc   s    r   r   zInotifyEvent.is_ignored+  s    zz,777!;;r!   c                z    | j                   xs. | j                  xs  | j                  t        j                  z  dkD  S r}   )r   r   r   r   r:   rc   s    r   r   zInotifyEvent.is_directory/  s=      :  :zz,5559	
r!   c                t    | j                   | j                  | j                  | j                  | j                  fS r   )r   r   r   r   r   rc   s    r   keyzInotifyEvent.key:  s'    ~~txxT\\4::MMr!   c                4    | j                   |j                   k(  S r   r   r]   r   s     r   __eq__zInotifyEvent.__eq__>      xx=,,,,r!   c                4    | j                   |j                   k7  S r   r   r   s     r   __ne__zInotifyEvent.__ne__A  r   r!   c                ,    t        | j                        S r   )hashr   rc   s    r   __hash__zInotifyEvent.__hash__D  s    DHH~r!   c                    g }t        t              D ]@  }|j                  d      s|dvst        t        |      }| |z  s0|j	                  |       B dj                  |      S )NIN_)r<   r1   r2   |)dirr   r   getattrr   r   )rC   maskscc_vals       r   _get_mask_stringzInotifyEvent._get_mask_stringG  se    %& 	$A||E"q 1 (
   0!4%<LLO	$ xxr!   c                    dt        |       j                   d| j                  d| j                   d| j	                  | j
                         d| j                   dt        j                  | j                        dS )N<z: src_path=z, wd=z, mask=z	, cookie=z, name=>)
typer"   rm   rB   r   rC   rD   rW   fsdecoderF   rc   s    r   __repr__zInotifyEvent.__repr__U  ss    T
##$K/@dggY O**49956i} M[[+.a1	
r!   N)!r"   r#   r$   rG   ra   r   rm   rB   rC   rD   rF   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r   r!   r   r   r     s   "           ; ; @ @ B B 9 9 ; ; ; ; @ @ ; ; ? ? = = 9 9 > > ; ; < < 
 
 N N--  
r!   r   )+
__future__r   r   ctypes.utilr   rW   r   rO   r   r   r   	functoolsr   watchdog.utilsr   CDLLlibchasattrr   	CFUNCTYPEr
   r   r	   r   r&   r'   r+   r,   r-   r.   r/   r7   r(   r*   r   	StructurerA   sizeof
EVENT_SIZEDEFAULT_NUM_EVENTSr   rJ   r   r   r!   r   <module>r     s    #    	   , ,  *v{{4 	n%4,-4+,
<TZZLI
JJV$F$$UE8XQUV$  L#6##E5(dK  7v67MN5 5r """"&&$$""""''''''   "6++ . V]]/0
 .*r/B r) r)j	N
 N
r!   