2121 raises = None
2222
2323from ..fuse_impl import llfuse , has_any_fuse , has_llfuse , has_pyfuse3 , has_mfusepy , ENOATTR # NOQA
24- from .. import platform
24+ from .. import platform as borg_platform
2525from ..platformflags import is_win32 , is_darwin
2626
2727# Does this version of llfuse support ns precision?
3232has_lchflags = hasattr (os , "lchflags" ) or sys .platform .startswith ("linux" )
3333try :
3434 with tempfile .NamedTemporaryFile () as file :
35- platform .set_flags (file .name , stat .UF_NODUMP )
35+ borg_platform .set_flags (file .name , stat .UF_NODUMP )
3636except OSError :
3737 has_lchflags = False
3838
@@ -52,6 +52,9 @@ def same_ts_ns(ts_ns1, ts_ns2):
5252 """Compare two timestamps (both in nanoseconds) to determine whether they are (roughly) equal."""
5353 diff_ts = int (abs (ts_ns1 - ts_ns2 ))
5454 diff_max = 10 ** (- st_mtime_ns_round )
55+ # On Windows, we generally have to expect up to 10ms variance.
56+ if is_win32 :
57+ diff_max = max (diff_max , 10 * 1000 * 1000 )
5558 return diff_ts <= diff_max
5659
5760
@@ -187,40 +190,49 @@ def is_utime_fully_supported():
187190 # Some filesystems (such as SSHFS) don't support utime on symlinks
188191 if are_symlinks_supported ():
189192 os .symlink ("something" , filepath )
193+ try :
194+ os .utime (filepath , (1000 , 2000 ), follow_symlinks = False )
195+ new_stats = os .stat (filepath , follow_symlinks = False )
196+ if new_stats .st_atime == 1000 and new_stats .st_mtime == 2000 :
197+ return True
198+ except OSError :
199+ pass
200+ except NotImplementedError :
201+ pass
190202 else :
191203 open (filepath , "w" ).close ()
192- try :
193- os .utime (filepath , (1000 , 2000 ), follow_symlinks = False )
194- new_stats = os .stat (filepath , follow_symlinks = False )
195- if new_stats .st_atime == 1000 and new_stats .st_mtime == 2000 :
196- return True
197- except OSError :
198- pass
199- except NotImplementedError :
200- pass
201- return False
204+ try :
205+ os .utime (filepath , (1000 , 2000 ))
206+ new_stats = os .stat (filepath )
207+ if new_stats .st_atime == 1000 and new_stats .st_mtime == 2000 :
208+ return True
209+ except OSError :
210+ pass
211+ return False
202212
203213
204214@functools .lru_cache
205215def is_birthtime_fully_supported ():
206- if not hasattr (os .stat_result , "st_birthtime" ):
207- return False
208216 with unopened_tempfile () as filepath :
209217 # Some filesystems (such as SSHFS) don't support utime on symlinks
210218 if are_symlinks_supported ():
211219 os .symlink ("something" , filepath )
212220 else :
213221 open (filepath , "w" ).close ()
214222 try :
215- birthtime , mtime , atime = 946598400 , 946684800 , 946771200
216- os .utime (filepath , (atime , birthtime ), follow_symlinks = False )
217- os .utime (filepath , (atime , mtime ), follow_symlinks = False )
218- new_stats = os .stat (filepath , follow_symlinks = False )
219- if new_stats .st_birthtime == birthtime and new_stats .st_mtime == mtime and new_stats .st_atime == atime :
223+ birthtime_ns , mtime_ns , atime_ns = 946598400 * 10 ** 9 , 946684800 * 10 ** 9 , 946771200 * 10 ** 9
224+ borg_platform .set_birthtime (filepath , birthtime_ns )
225+ os .utime (filepath , ns = (atime_ns , mtime_ns ))
226+ new_stats = os .stat (filepath )
227+ bt = borg_platform .get_birthtime_ns (new_stats , filepath )
228+ if (
229+ bt is not None
230+ and same_ts_ns (bt , birthtime_ns )
231+ and same_ts_ns (new_stats .st_mtime_ns , mtime_ns )
232+ and same_ts_ns (new_stats .st_atime_ns , atime_ns )
233+ ):
220234 return True
221- except OSError :
222- pass
223- except NotImplementedError :
235+ except (OSError , NotImplementedError , AttributeError ):
224236 pass
225237 return False
226238
0 commit comments