3 uAc@sdZddlmZdeekr eZdddddgZdd lZdd l Z dd l Z dd l Z dd l Z d Z d d Zgfd dZddZdddZdddZdddZdddZd S)z=This module contains helper functions for dealing with files.)absolute_importxrange issamefilelinkfilecopyfilelinkorcopyfileoverwrite_safelyNicCs"tj|}tj|}tjj||S)N)osstatpathsamestat)path1path2s1s2r/usr/lib/python3.6/files.py _issamefile+s  rc Cs0|dkr t}y t||S|k r*dSXdS)zECheck whether two paths point to the same file (i.e. are hardlinked).TFN) Exceptionr)r rcatch_stat_exceptionsrrrr2s  cCst||tdrdStjj|}tjj|}tjj|}d}xpttj D]b}tj |tj |d}ytj ||Wn2tk r}z|j t jkrnWYdd}~XqFXd}PqFW|rtj||dS)zUHardlink srcpath to dstpath. Attempt to atomically replace dstpath if it exists.)rNF)prefixdirT)rOSErrorr r abspathdirnamebasenamerangetempfileTMP_MAXmktempextseplinkerrnoEEXISTrename)srcpathdstpathdstdnamedstbnameZ hardlinkedattempt_dsttmperrrr>s$    Tc Cs8t||tdrdStjj|}tjj|}tjj|}t|d}tj |tjj |dd}tj |}|rytj |}Wntk rYnXtj |j t j|jd} xP| dkr|jt} y|j| Wq|j|jtj|jYqXqW|j|jtj|j||r4tjdkr4tj|dS)zCopy srcpath to dstpath. Abort operation if e.g. not enough space is available. Attempt to atomically replace dstpath if it exists.)rNrbF)rrdeleter)rrr r rrropenrZNamedTemporaryFiler r fchmodfilenoS_IMODEst_moderead BLOCKSIZEwritecloseunlinknamer$selinuxis_selinux_enabled restorecon) r%r&copy_mode_from_dstrun_restoreconr'r(ZsrcfileZ dsttmpfilesdatarrrr_s<         cCs^yt||dStk rJ}z |jtjtjtjfkr:nWYdd}~XnXt||||dS)ztFirst attempt to hardlink srcpath to dstpath, if hardlinking isn't possible, attempt copying srcpath to dstpath.N)rrr"ZEMLINKZEPERMZEXDEVr)r%r&r=r>r+rrrrs Fc Cstjj|}tjj|}d}d}|r6tjdkr6d}n^y&tj|\}}|dkrZtd|Wn6tk r} z| j t j krd}nWYdd} ~ XnX|stj |||rtj |nd} xtt tjD]f} tj|tj|d} ytj || Wn6tk r"} z| j t jkrwĂWYdd} ~ XqX| } PqW| dkrDtt jd|r^| r^tj| |ytj| |Wntj| YnX|rtj |dS)zpCreate a symlink, optionally replacing dstpath atomically, optionally setting or preserving SELinux context.FNrzgetfilecon(%r) failedT)rrz/No suitable temporary symlink could be created.)r r rrr:r;Z lgetfilecon RuntimeErrorrr"ENOENTsymlinkr<rrrrr r#IOErrorZ lsetfileconr$remove) r%r&forcepreserve_contextr'r(r>ctxretr+Zdsttmpr)r*rrrsymlink_atomicallysV        rJcCs~tjj|}tjj|}tjj|}d}d}d} tjj|} |rPtjdkrPd}ztj |tjj |d\}} | rtj |} |rtj || j | j|rtj|t j| j|rtj|\} } | dkrtd|tj|d}d}|j||jd}tj| ||r$| rtj|| n tj|Wd|r8|jn|rHtj|| rxtjj| rxytj| Wn YnXXdS)zSafely overwrite a file by creating a temporary file in the same directory, writing it, moving it over the original file, eventually preserving file mode, SELinux context and ownership.NrF)rrzgetfilecon(%r) failedw)r r realpathrrexistsr:r;rZmkstempr r fchownst_uidst_gidr0r2r3Z getfileconrAfdopenr6r7r$Z setfileconr<isfiler8)r ZcontentZ preserve_moderGZpreserve_ownershipZdir_basefdfZtmpnamerMr?rIrHrrrrsR            )TT)TT)FT)TTT)__doc__Z __future__rr __builtins__rr__all__r r:rr"r r5rrrrrrJrrrrrs&   ! 5  ?