
                             S r SSKJr  SSKrSSKrSSKrSSKrSSKJr  Sr	\R                  " \5      r " S S\5      r " S S	\5      rS
 r " S S\5      r " S S\5      r " S S\5      rg)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                       \ rS rSrSrSrg) CredentialsFileSymbolicLinkError0   z-Credentials files must not be symbolic links. N__name__
__module____qualname____firstlineno____doc____static_attributes__r       3lib/third_party/oauth2client/contrib/locked_file.pyr   r   0   s    7r   r   c                       \ rS rSrSrSrg)AlreadyLockedException4   zETrying to lock a file that has already been locked by the LockedFile.r   Nr	   r   r   r   r   r   4   s    Or   r   c                     [         R                  R                  U 5      (       a  [        SR	                  U 5      5      eg )NzFile: {0} is a symbolic link.)ospathislinkr   format)filenames    r   validate_filer   9   s5    	ww~~h.+228<> 	>  r   c                   <    \ rS rSrSrS rS rS rS rS r	S r
S	rg
)_Opener?   z,Base class for different locking primitives.c                 R    SU l         Xl        X l        X0l        SU l        SU l        g)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___Opener.__init__B   s)     !
+r   c                     U R                   $ )zWas the file locked.)r    r&   s    r   	is_locked_Opener.is_lockedQ   s    ||r   c                     U R                   $ )z5The file handle to the file. Valid only after opened.)r$   r,   s    r   file_handle_Opener.file_handleU   s    xxr   c                     U R                   $ )z"The filename that is being locked.)r!   r,   s    r   r   _Opener.filenameY   s    ~~r   c                     g)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_lock_Opener.open_and_lock]   s     	r   c                     g)zUnlock and close the file.Nr   r,   s    r   unlock_and_close_Opener.unlock_and_closef   s    r   )r#   r$   r!   r%   r    r"   N)r
   r   r   r   r   r)   r-   r0   r   r8   r;   r   r   r   r   r   r   ?   s#    6r   r   c                   *    \ rS rSrSrS rS rS rSrg)_PosixOpenerk   z+Lock files using Posix advisory lock files.c                 f   U R                   (       a$  [        SR                  U R                  5      5      eSU l         [	        U R                  5         [        U R                  U R                  5      U l        U R                  U R                  5      n[        R                  " 5       n  [        R
                  " U[        R                  [        R                   -  [        R"                  -  5      U l        SU l         g! [         aR  nUR                  [        R                  :X  a*  [        U R                  U R                  5      U l         SnAg SnANSnAff = f! [&         a  nUR                  [        R(                  :w  a  e [        R                  " 5       U-
  U:  ak  [*        R-                  SXA5        U R                  (       a  U R                  R/                  5         [        U R                  U R                  5      U l         SnAg[        R0                  " U5         SnAOSnAff = fGM  )aw  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&   r6   r7   elock_filename
start_times         r   r8   _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 -8 xx(#DNND4G4GHDH

5!!" s9   %C> *AE >
EAEE
H-'B!H(H((H-c                 <   U R                   (       a_  U R                  U R                  5      n[        R                  " U R
                  5        [        R                  " U5        SU l         SU l        U R                  (       a  U R                  R	                  5         gg)z?Unlock a file by removing the .lock file, and close the handle.FN)r    rE   r!   r   rN   r%   unlinkr$   )r&   rQ   s     r   r;   _PosixOpener.unlock_and_close   sa    << 00@MHHT]]#IIm$ DL DM88HHNN r   c                 $    SR                  U5      $ )z3The name of the lock file to use for posix locking.z{0}.lock)r   )r&   r   s     r   rE   _PosixOpener._posix_lockfile   s      **r   )r$   r%   r    N)	r
   r   r   r   r   r8   r;   rE   r   r   r   r   r>   r>   k   s    50"d	+r   r>   c                   n    \ rS rSrSr\R                  " S5      SS j5       rS rS r	S r
SS jrS	 rS
rg)
LockedFile   z+Represent a file that has exclusive access.   c                     SnU(       d  U(       a   SSK Jn  U" XU5      nU(       d  [        XU5      nXPl        g! [         a$     SSKJn  U" XU5      n N6! [         a      NCf = ff = f)a+  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_openerr^   ImportError"oauth2client.contrib._fcntl_openerr_   r>   _opener)r&   r   r'   r(   use_native_lockingopenerr^   r_   s           r   r)   LockedFile.__init__   sp     ,K%hmD !(-@F  O)(-HF" 	s'   ; 
A)A
A%!A)$A%%A)c                 .    U R                   R                  $ )z-Return the filename we were constructed with.)rc   r!   r,   s    r   r   LockedFile.filename   s    ||%%%r   c                 6    U R                   R                  5       $ )z*Return the file_handle to the opened file.)rc   r0   r,   s    r   r0   LockedFile.file_handle   s    ||''))r   c                 6    U R                   R                  5       $ )z/Return whether we successfully locked the file.)rc   r-   r,   s    r   r-   LockedFile.is_locked   s    ||%%''r   c                 :    U R                   R                  X5        g)a  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)rc   r8   r5   s      r   r8   LockedFile.open_and_lock   s     	""72r   c                 8    U R                   R                  5         g)zUnlock and close a file.N)rc   r;   r,   s    r   r;   LockedFile.unlock_and_close   s    %%'r   )rc   N)T)r   g?)r
   r   r   r   r   r   
positionalr)   r   r0   r-   r8   r;   r   r   r   r   rZ   rZ      s9    5	__Q 6&*(3(r   rZ   )r   
__future__r   rC   loggingr   rF   oauth2clientr   
__author__	getLoggerr
   rL   	Exceptionr   r   r   objectr   r>   rZ   r   r   r   <module>ry      sz   $ &   	   4
			8	$8y 8	Y 	
>)f )XB+7 B+J:( :(r   