
    F                         S r SrSSKrSSKrSSKrSSKrSSKrSSKr " S S\5      r	S r
S rSS jrSS	 jrSS
 jrS rSS jrg)zSimple file system utilities.)z"elaforge@google.com (Evan LaForge)z%matthewb@google.com (Matthew Blecker)    Nc                       \ rS rSrSrSrg)PasswdError   z:Exception class for errors loading a password from a file. N)__name__
__module____qualname____firstlineno____doc____static_attributes__r       4platform/bq/third_party/google/apputils/file_util.pyr   r      s    Br   r   c                     [         R                  " U 5       Vs/ s H"  n[         R                  R                  X5      PM$     sn$ s  snf )zHLike os.listdir with prepended dir_name, which is often more convenient.)oslistdirpathjoin)dir_namefns     r   ListDirPathr   !   s2    /1zz(/C	D/C"'',,x
$/C	DD	Ds   )Ac                     [        U 5      n UR                  5       UR                  5         $ ! UR                  5         f = f)z2Read entire contents of file with name 'filename'.)openreadclose)filenamefps     r   Readr   &   s,    H~"779HHJBHHJs   - ?c                 Z   [         R                  [         R                  -  [         R                  -  nU(       d  U[         R                  -  n[         R
                  " XU5      n [         R                  " XQ5        [         R                  " U5        g! [         R                  " U5        f = f)a  Create a file 'filename' with 'contents', with the mode given in 'mode'.

The 'mode' is modified by the umask, as in open(2).  If
'overwrite_existing' is False, the file will be opened in O_EXCL mode.

Args:
  filename: str; the name of the file
  contents: str; the data to write to the file
  overwrite_existing: bool; whether or not to allow the write if the file
                      already exists
  mode: int; permissions with which to create the file (default is 0666 octal)
N)r   O_WRONLYO_TRUNCO_CREATO_EXCLr   writer   )r   contentsoverwrite_existingmodeflagsfds         r   Writer)   /   sh     ++


"RZZ
/%		RYYE	wwx%"HHRHHRLBHHRLs   %B B*c                    [         R                  " [        R                  R	                  U 5      S9u  p4 [        R
                  " X15        [        R                  " U5         [        R                  " XB5        [        R                  " X@5        g! [        R                  " U5        f = f! [         aH  n [        R                  " U5        Ue! [         a  n[        U< SU< 35      n SnAUeSnAff = fSnAff = f)a  Create a file 'filename' with 'contents' atomically.

As in Write, 'mode' is modified by the umask.  This creates and moves
a temporary file, and errors doing the above will be propagated normally,
though it will try to clean up the temporary file in that case.

This is very similar to the prodlib function with the same name.

Args:
  filename: str; the name of the file
  contents: str; the data to write to the file
  mode: int; permissions with which to create the file (default is 0666 octal)
)dirz!. Additional errors cleaning up: N)tempfilemkstempr   r   dirnamer#   r   chmodrenameOSErrorremove)r   r$   r&   r(   tmp_filenameexces          r   AtomicWriter6   F   s      ''BGGOOH,EF2HHRHHRLHH\ IIl% HHRL 
 Hii I  HsAFGc
IHsG   B ",B* B'*
C<5CC7
C4C/)C7/C44C77C<c                 V   [         R                  R                  U 5      nUR                  [         R                  R                  5      n[        S[        U5      5       Hm  n[         R                  R                  R                  USUS-    5      n U(       a3  [         R                  " U5        Ub  [         R                  " XQ5        Mk  Mm  Mo     g! [         aN  nUR                  [        R                  :X  a$  [         R                  R                  U5      (       d  e  SnAM  SnAff = f)aD  Makes a directory including its parent directories.

This function is equivalent to os.makedirs() but it avoids a race
condition that os.makedirs() has.  The race is between os.mkdir() and
os.path.exists() which fail with errors when run in parallel.

Args:
  directory: str; the directory to make
  force_mode: optional octal, chmod dir to get rid of umask interaction
Raises:
  Whatever os.mkdir() raises when it fails for any reason EXCLUDING
  "dir already exists".  If a directory already exists, it does not
  raise anything.  This behaviour is different than os.makedirs()
r   N   )r   r   normpathsplitseprangelenr   mkdirr/   r1   errnoEEXISTisdir)	directory
force_modenamedirsir   r4   s          r   MkDirsrG   d   s     
		)	$$	BGGKK	 $CIa77;;D!A#J'D	
!
((4
$ " 
   ii5<<'BGGMM$,?,? -@s   6C
D(AD##D(c                 d    [         R                  " U 5         [
        R                  R                  U 5      nU(       a@   [
        R                  " U5        [
        R                  R                  U5      nU(       a  M?  gg! [         a)  nUR                  [        R                  :w  a  e  SnANSnAff = f! [         a)  nUR                  [        R                  :w  a  e  SnANSnAff = f! [         a9  nUR                  [        R                  [        R                  4;  a  e  SnAgSnAff = f)zRemoves dir_name and every non-empty directory in dir_name.

Unlike os.removedirs and shutil.rmtree, this function doesn't raise an error
if the directory does not exist.

Args:
  dir_name: Directory to be removed.
N)shutilrmtreer1   r?   ENOENTr   r   r.   rmdirEACCES	ENOTEMPTY)r   errparent_directorys      r   RmDirsrQ      s    
MM(
wwx0

!"
 )9: 
 
 
yyELL  !  99$
 %
 
 
yyu77 8sX   B  &C,  B6 &C,  
B3
B..B36
C) C$C, $C))C, ,
D/6/D**D/c                 d   U c5  [         R                  " [        R                  " 5       5      nUR                  $ [	        U [
        5      (       a"  [         R                  " U 5      nUR                  $ [	        U [        5      (       a"  [         R                  " U 5      nUR                  $ [        S5      e)a$  Find the home directory of a user.

Args:
  user: int, str, or None - the uid or login of the user to query for,
        or None (the default) to query for the current process' effective user

Returns:
  str - the user's home directory

Raises:
  TypeError: if user is not int, str, or None.
z.user must be None or an instance of int or str)
pwdgetpwuidr   geteuid
isinstanceintstrgetpwnam	TypeErrorpw_dir)user	pw_structs     r   HomeDirr^      s     
\RZZ\*I 
		 $T"I
 
			 $T"I 
		 D
EEr   )T  )r_   )N)r   
__author__r?   r   rS   rI   statr,   	Exceptionr   r   r   r)   r6   rG   rQ   r^   r   r   r   <module>rc      sW     $7
  	 
   C) CE
.<<<r   