
                             d Z ddlmZ ddlZddlZddlZddlZddlmZ dZ	 ej                  e      Z G d de      Z G d d	e      Zd
 Z G d de      Z G d de      Z G d de      Zy)a  Locked file interface that should work on Unix and Windows pythons.

This module first tries to use fcntl locking to ensure serialized access
to a file, then falls back on a lock file if that is unavialable.

Usage::

    f = LockedFile('filename', 'r+b', 'rb')
    f.open_and_lock()
    if f.is_locked():
      print('Acquired filename with r+b mode')
      f.file_handle().write('locked data')
    else:
      print('Acquired filename with rb mode')
    f.unlock_and_close()

    )print_functionN)utilz$cache@google.com (David T McWherter)c                       e Zd ZdZy) CredentialsFileSymbolicLinkErrorz-Credentials files must not be symbolic links.N__name__
__module____qualname____doc__     3lib/third_party/oauth2client/contrib/locked_file.pyr   r   0   s    7r   r   c                       e Zd ZdZy)AlreadyLockedExceptionzETrying to lock a file that has already been locked by the LockedFile.Nr   r   r   r   r   r   4   s    Or   r   c                 v    t         j                  j                  |       rt        dj	                  |             y )NzFile: {0} is a symbolic link.)ospathislinkr   format)filenames    r   validate_filer   9   s2    	ww~~h.+228<> 	>  r   c                   4    e Zd ZdZd Zd Zd Zd Zd Zd Z	y)	_Openerz,Base class for different locking primitives.c                 X    d| _         || _        || _        || _        d| _        d| _        y)zCreate an Opener.

        Args:
            filename: string, The pathname of the file.
            mode: string, The preferred mode to access the file with.
            fallback_mode: string, The mode to use if locking fails.
        FN)_locked	_filename_mode_fallback_mode_fh_lock_fd)selfr   modefallback_modes       r   __init__z_Opener.__init__B   s/     !
+r   c                     | j                   S )zWas the file locked.)r   r!   s    r   	is_lockedz_Opener.is_lockedQ   s    ||r   c                     | j                   S )z5The file handle to the file. Valid only after opened.)r   r&   s    r   file_handlez_Opener.file_handleU   s    xxr   c                     | j                   S )z"The filename that is being locked.)r   r&   s    r   r   z_Opener.filenameY   s    ~~r   c                      y)zOpen the file and lock it.

        Args:
            timeout: float, How long to try to lock for.
            delay: float, How long to wait between retries.
        Nr   r!   timeoutdelays      r   open_and_lockz_Opener.open_and_lock]   s     	r   c                      y)zUnlock and close the file.Nr   r&   s    r   unlock_and_closez_Opener.unlock_and_closef   s    r   N)
r   r	   r
   r   r$   r'   r)   r   r/   r1   r   r   r   r   r   ?   s#    6r   r   c                   "    e Zd ZdZd Zd Zd Zy)_PosixOpenerz+Lock files using Posix advisory lock files.c                 @   | j                   r$t        dj                  | j                              d| _         t	        | j                         	 t        | j                  | j                        | _        | j                  | j                        }t        j                         }	 	 t        j
                  |t        j                  t        j                   z  t        j"                  z        | _        d| _         y# t        $ rQ}|j                  t        j                  k(  r*t        | j                  | j                        | _        Y d}~yY d}~d}~ww xY w# t&        $ r}|j                  t        j(                  k7  r t        j                         |z
  |k\  rgt*        j-                  d||       | j                  r| j                  j/                          t        | j                  | j                        | _        Y d}~yt        j0                  |       Y d}~nd}~ww xY w})a  Open the file and lock it.

        Tries to create a .lock file next to the file we're trying to open.

        Args:
            timeout: float, How long to try to lock for.
            delay: float, How long to wait between retries.

        Raises:
            AlreadyLockedException: if the lock is already acquired.
            IOError: if the open fails.
            CredentialsFileSymbolicLinkError if the file is a symbolic link.
        zFile {0} is already lockedFNTz'Could not acquire lock %s in %s seconds)r   r   r   r   r   openr   r   IOErrorerrnoEACCESr   _posix_lockfiletimer   O_CREATO_EXCLO_RDWRr    OSErrorEEXISTloggerwarnclosesleep)r!   r-   r.   elock_filename
start_times         r   r/   z_PosixOpener.open_and_lockn   s    <<(,33DNNCE Ednn%	DNNDJJ7DH ,,T^^<YY[
" "(*

RYY(>(J!L#  	ww%,,&0C0CD '	  "77ell*IIK*,8KK I -w8 xx(#DNND4G4GHDH

5!!" s9   %C7 $AE 7	E AEE	HBH<HHc                 $   | j                   r]| j                  | j                        }t        j                  | j
                         t        j                  |       d| _         d| _        | j                  r| j                  j	                          yy)z?Unlock a file by removing the .lock file, and close the handle.FN)r   r9   r   r   rB   r    unlinkr   )r!   rE   s     r   r1   z_PosixOpener.unlock_and_close   sa    << 00@MHHT]]#IIm$ DL DM88HHNN r   c                 $    dj                  |      S )z3The name of the lock file to use for posix locking.z{0}.lock)r   )r!   r   s     r   r9   z_PosixOpener._posix_lockfile   s      **r   N)r   r	   r
   r   r/   r1   r9   r   r   r   r3   r3   k   s    50"d	+r   r3   c                   b    e Zd ZdZ ej
                  d      d
d       Zd Zd Zd Z	ddZ
d Zy	)
LockedFilez+Represent a file that has exclusive access.   c                     d}|s|r	 ddl m}  ||||      }|st        |||      }|| _        y# t        $ r$ 	 ddlm}  ||||      }n# t        $ r Y nw xY wY Cw xY w)ac  Construct a LockedFile.

        Args:
            filename: string, The path of the file to open.
            mode: string, The mode to try to open the file with.
            fallback_mode: string, The mode to use if locking fails.
            use_native_locking: bool, Whether or not fcntl/win32 locking is
                                used.
        Nr   )_Win32Opener)_FcntlOpener)"oauth2client.contrib._win32_openerrN   ImportError"oauth2client.contrib._fcntl_openerrO   r3   _opener)r!   r   r"   r#   use_native_lockingopenerrN   rO   s           r   r$   zLockedFile.__init__   sx     ,K%hmD !(D-@F  O)(D-HF" 	s2   / 	AA
	A
	AAAAAc                 .    | j                   j                  S )z-Return the filename we were constructed with.)rS   r   r&   s    r   r   zLockedFile.filename   s    ||%%%r   c                 6    | j                   j                         S )z*Return the file_handle to the opened file.)rS   r)   r&   s    r   r)   zLockedFile.file_handle   s    ||''))r   c                 6    | j                   j                         S )z/Return whether we successfully locked the file.)rS   r'   r&   s    r   r'   zLockedFile.is_locked   s    ||%%''r   c                 <    | j                   j                  ||       y)aU  Open the file, trying to lock it.

        Args:
            timeout: float, The number of seconds to try to acquire the lock.
            delay: float, The number of seconds to wait between retry attempts.

        Raises:
            AlreadyLockedException: if the lock is already acquired.
            IOError: if the open fails.
        N)rS   r/   r,   s      r   r/   zLockedFile.open_and_lock   s     	""7E2r   c                 8    | j                   j                          y)zUnlock and close a file.N)rS   r1   r&   s    r   r1   zLockedFile.unlock_and_close   s    %%'r   N)T)r   g?)r   r	   r
   r   r   
positionalr$   r   r)   r'   r/   r1   r   r   r   rK   rK      s;    5T__Q 6&*(3(r   rK   )r   
__future__r   r7   loggingr   r:   oauth2clientr   
__author__	getLoggerr   r@   	Exceptionr   r   r   objectr   r3   rK   r   r   r   <module>rc      s|   $ &   	   4
			8	$8y 8	Y 	
>)f )XB+7 B+J:( :(r   