o
    *ήcCK                     @   sj  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 d dlmZm	Z	m
Z
 d dlmZ edZeedrBeedrBeedsIedej ejeee	e
d	d
defZejeee
d	d
defZejed	d
defZG dd dZedd ejejejejejejejejejg	ZG dd dej Z!e"e!Z#dZ$e$e#d  Z%G dd dZ&G dd dZ'dS )    N)reduce)c_intc_char_pc_uint32)UnsupportedLibcinotify_initinotify_add_watchinotify_rm_watchz"Unsupported libc version found: %sT)	use_errnoc                   @   s   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B Ze	e
B ZdZdZdZdZdZdZdZdZdZedd eeeeeee	e
eeeegZdZdZdS )InotifyConstants                   @         i   i      i    i @  i   i   i   i   i    i   @l        c                 C      | |B S N xyr   r   C/tmp/pip-target-vg8gfxp4/lib/python/watchdog/observers/inotify_c.py<lambda>O       zInotifyConstants.<lambda>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   -   sT    r   c                 C   r   r   r   r   r   r   r   r   e   r   r   c                   @   s2   e Zd ZdZdefdefdefdefdefgZdS )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   r   r<   r   s    r<   r   r   c                   @   s   e Zd ZdZdefddZedd Zedd Zed	d
 Z	edd Z
dd Zdd Zdd Zdd Zdd Zdd ZefddZdd Zdd Zedd  Zed!d" Zd#S )$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                 C   s|   t  }|dkrt  || _t | _t | _t | _	|| _
|| _|| _tj|r2| ||| n| || t | _d S )N)r   rD   _raise_error_inotify_fd	threadingLock_lockdict_wd_for_path_path_for_wd_path_event_mask_is_recursiveospathisdir_add_dir_watch
_add_watch_moved_from_events)selfrR   	recursive
event_mask
inotify_fdr   r   r   __init__   s   
zInotify.__init__c                 C      | j S )z)The event mask for this inotify instance.)rO   rW   r   r   r   rY         zInotify.event_maskc                 C   r\   )z.The path associated with the inotify instance.)rN   r]   r   r   r   rR      r^   zInotify.pathc                 C   r\   )z0Whether we are watching directories recursively.)rP   r]   r   r   r   is_recursive   r^   zInotify.is_recursivec                 C   r\   )z9The file descriptor associated with the inotify instance.)rG   r]   r   r   r   fd   r^   z
Inotify.fdc                 C   s   t  | _dS )z)Clear cached records of MOVED_FROM eventsN)rK   rV   r]   r   r   r   clear_move_records   s   zInotify.clear_move_recordsc                 C   s   |j | jv r| j|j  jS dS )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)r?   rV   src_path)rW   destination_eventr   r   r   source_for_move   s   zInotify.source_for_movec                 C   s   || j |j< dS )zf
        Save this event as the source event for future MOVED_TO events to
        reference.
        N)rV   r?   )rW   eventr   r   r   remember_move_from_event   s   z Inotify.remember_move_from_eventc                 C   s:   | j  | || j W d   dS 1 sw   Y  dS )zn
        Adds a watch for the given path.

        :param path:
            Path to begin monitoring.
        N)rJ   rU   rO   )rW   rR   r   r   r   	add_watch   s   "zInotify.add_watchc                 C   sh   | j ' | j|}| j|= t| j|dkr"t  W d   dS W d   dS 1 s-w   Y  dS )z
        Removes a watch for the given path.

        :param path:
            Path string for which the watch will be removed.
        rE   N)rJ   rL   poprM   r	   rG   rD   rF   )rW   rR   r=   r   r   r   remove_watch   s   
"zInotify.remove_watchc              	   C   s   | j 5 | j| jv r| j| j }t| j| zt| j W n	 ty'   Y n	w W d   dS W d   dS 1 s;w   Y  dS )zQ
        Closes the inotify instance and removes all associated watches.
        N)rJ   rN   rL   r	   rG   rQ   closeOSError)rW   r=   r   r   r   rj      s   	"zInotify.closec              
      sP   fdd}d}	 z	t  j|}W n' ty9 } z|jtjkr&W Y d}~q|jtjkr4g W  Y d}~S  d}~ww 	  j g }t	|D ]\}}}}	|dkrQqF j
| }
|	r_t j|
|	n|
}t||||	|}|jrr | nb|jrԈ |}| jv rň j| } j|= | j|j< |j j
|<  jrň j  D ]&\}}||t jj  rĈ j|}|||j}| j|< | j
|< qt j|
|	}t||||	|}|jr j
|} j| |kr j|= ||  jr|jr|jrz	  | j! W n
 ty   Y qFw |"|| qFW d   |S 1 s!w   Y  |S )z<
        Reads events from inotify and yields them.
        c              
      s   g }t | D ]W\}}}|D ],}z!t j||} | j}t|tjtj	B d||}|
| W q ty:   Y qw |D ] }	t j||	} jt j| }
t|
tjd|	|}|
| q=q|S Nr   )rQ   walkrR   joinrU   rO   InotifyEventr   r*   r7   appendrk   rL   dirname)rb   eventsrootdirnames	filenamesrq   	full_pathwd_direfilenamewd_parent_dirr]   r   r   _recursive_simulate  s,   z0Inotify.read_events.<locals>._recursive_simulateNTrE   )#rQ   readrG   rk   errnoEINTREBADFrJ   rD   _parse_event_bufferrM   rR   rn   ro   is_moved_fromrf   is_moved_tord   rL   rb   r_   copyitems
startswithsepencoderh   replace
is_ignoredrp   is_directory	is_createrU   rO   extend)rW   event_buffer_sizer{   event_bufferrx   
event_listr=   r>   r?   rA   wd_pathrb   inotify_eventmove_src_pathmoved_wdrN   _wd_move_to_pathrR   r   r]   r   read_events   sz   	








55zInotify.read_eventsc           	      C   s   t j|sttjt tj|| || |r=t |D ] \}}}|D ]}t j	||}t j
|r5q%| || q%qdS dS )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)rQ   rR   rS   rk   r}   ENOTDIRstrerrorrU   rm   rn   islink)	rW   rR   rX   r>   rs   rt   _rq   rv   r   r   r   rT   _  s   zInotify._add_dir_watchc                 C   s6   t | j||}|dkrt  || 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.
        rE   )r   rG   rD   rF   rL   rM   )rW   rR   r>   r=   r   r   r   rU   v  s   


zInotify._add_watchc                  C   sR   t  } | tjkrttjd| tjkrttjd| tjkr!dS t| t| )z5
        Raises errors for inotify failures.
        zinotify watch limit reachedzinotify instance limit reachedN)	ctypes	get_errnor}   ENOSPCrk   EMFILEEACCESrQ   r   )errr   r   r   rF     s   


zInotify._raise_errorc                 c   s|    d}|d t | kr<td| |\}}}}| |d |d |  d}|d| 7 }||||fV  |d t | ksdS dS )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)r@   structunpack_fromrstrip)r   ir=   r>   r?   lengthrA   r   r   r   r     s   zInotify._parse_event_bufferN)r   r    r!   rB   WATCHDOG_ALL_EVENTSr[   propertyrY   rR   r_   r`   ra   rd   rf   rg   ri   rj   DEFAULT_EVENT_BUFFER_SIZEr   rT   rU   staticmethodrF   r   r   r   r   r   rD      s0    




b
rD   c                   @   s4  e Zd ZdZdd Zedd Zedd Zedd	 Zed
d Z	edd Z
edd Zedd Zedd Zedd Zedd Zedd Zedd Zedd Zedd Zed d! Zed"d# Zed$d% Zed&d' Zed(d) Zed*d+ Zd,d- Zd.d/ Zd0d1 Zed2d3 Zd4d5 Zd6S )7ro   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                 C   s"   || _ || _|| _|| _|| _d S r   )r   _mask_cookie_name	_src_path)rW   r=   r>   r?   rA   rb   r   r   r   r[     s
   
zInotifyEvent.__init__c                 C   r\   r   )r   r]   r   r   r   rb        zInotifyEvent.src_pathc                 C   r\   r   )r   r]   r   r   r   r=     r   zInotifyEvent.wdc                 C   r\   r   )r   r]   r   r   r   r>     r   zInotifyEvent.maskc                 C   r\   r   )r   r]   r   r   r   r?     r   zInotifyEvent.cookiec                 C   r\   r   )r   r]   r   r   r   rA     r   zInotifyEvent.namec                 C      | j tj@ dkS rl   )r   r   r#   r]   r   r   r   	is_modify     zInotifyEvent.is_modifyc                 C   r   rl   )r   r   r%   r]   r   r   r   is_close_write  r   zInotifyEvent.is_close_writec                 C   r   rl   )r   r   r&   r]   r   r   r   is_close_nowrite  r   zInotifyEvent.is_close_nowritec                 C   r   rl   )r   r   r"   r]   r   r   r   	is_access  r   zInotifyEvent.is_accessc                 C   r   rl   )r   r   r+   r]   r   r   r   	is_delete  r   zInotifyEvent.is_deletec                 C   r   rl   )r   r   r,   r]   r   r   r   is_delete_self  r   zInotifyEvent.is_delete_selfc                 C   r   rl   )r   r   r*   r]   r   r   r   r     r   zInotifyEvent.is_createc                 C   r   rl   )r   r   r(   r]   r   r   r   r     r   zInotifyEvent.is_moved_fromc                 C   r   rl   )r   r   r)   r]   r   r   r   r     r   zInotifyEvent.is_moved_toc                 C   r   rl   )r   r   r/   r]   r   r   r   is_move  r   zInotifyEvent.is_movec                 C   r   rl   )r   r   r-   r]   r   r   r   is_move_self  r   zInotifyEvent.is_move_selfc                 C   r   rl   )r   r   r$   r]   r   r   r   	is_attrib	  r   zInotifyEvent.is_attribc                 C   r   rl   )r   r   r2   r]   r   r   r   r     r   zInotifyEvent.is_ignoredc                 C   s   | j p| jp| jtj@ dkS rl   )r   r   r   r   r7   r]   r   r   r   r     s   zInotifyEvent.is_directoryc                 C   s   | j | j| j| j| jfS r   )r   r   r   r   r   r]   r   r   r   key  s   zInotifyEvent.keyc                 C   s   | j |j kS r   r   rW   r   r   r   r   __eq__     zInotifyEvent.__eq__c                 C   s   | j |j kS r   r   r   r   r   r   __ne__   r   zInotifyEvent.__ne__c                 C   s
   t | jS r   )hashr   r]   r   r   r   __hash__#  s   
zInotifyEvent.__hash__c                 C   sN   g }t tD ]}|dr|dvrtt|}| |@ r|| qd|}|S )NIN_)r9   r.   r/   |)dirr   r   getattrrp   rn   )r>   maskscc_valmask_stringr   r   r   _get_mask_string&  s   


zInotifyEvent._get_mask_stringc              	   C   s8   |  | j}d}|t| j| j| j|| jt| j	f S )Nz5<%s: src_path=%r, wd=%d, mask=%s, cookie=%d, name=%s>)
r   r>   typer   rb   r=   r?   rQ   fsdecoderA   )rW   r   sr   r   r   __repr__1  s
   zInotifyEvent.__repr__N) r   r    r!   rB   r[   r   rb   r=   r>   r?   rA   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   ro     sb    





















ro   )(rQ   r}   r   rH   r   ctypes.util	functoolsr   r   r   r   watchdog.utilsr   CDLLlibchasattrr   	CFUNCTYPEr   r	   r   r   r#   r$   r(   r)   r*   r+   r,   r4   r%   r   	Structurer<   sizeof
EVENT_SIZEDEFAULT_NUM_EVENTSr   rD   ro   r   r   r   r   <module>   s^   

7
  )