1 """Enhanced stat operations for bup."""
3 from bup import _helpers
7 _have_utimensat = _helpers.utimensat
8 except AttributeError, e:
9 _have_utimensat = False
13 # Class to represent filesystem timestamps. Use integer
14 # nanoseconds on platforms where we have the higher resolution
15 # lstat. Use the native python stat representation (floating
16 # point seconds) otherwise.
19 return self._value.__cmp__(x._value)
22 return 'FSTime(%d)' % self._value
24 def to_timespec(self):
25 """Return (s, ns) where ns is always non-negative
26 and t = s + ns / 10e8""" # metadata record rep (and libc rep)
27 s_ns = self.secs_nsecs()
28 if s_ns[0] > 0 or s_ns[1] >= 0:
30 return (s_ns[0] - 1, 10**9 + s_ns[1]) # ns is negative
35 ts._value = int(round(secs * 10**9))
39 def from_timespec(timespec):
41 ts._value = timespec[0] * 10**9 + timespec[1]
44 def approx_secs(self):
45 return self._value / 10e8;
48 "Return a (s, ns) pair: -1.5s -> (-1, -10**9 / 2)."
50 return (self._value / 10**9, self._value % 10**9)
51 abs_val = -self._value
52 return (- (abs_val / 10**9), - (abs_val % 10**9))
56 def lutime(path, times):
57 atime = times[0].to_timespec()
58 mtime = times[1].to_timespec()
59 return _helpers.utimensat(_helpers.AT_FDCWD, path, (atime, mtime),
60 _helpers.AT_SYMLINK_NOFOLLOW)
61 def utime(path, times):
62 atime = times[0].to_timespec()
63 mtime = times[1].to_timespec()
64 return _helpers.utimensat(_helpers.AT_FDCWD, path, (atime, mtime), 0)
66 def lutime(path, times):
69 def utime(path, times):
70 atime = times[0].approx_secs()
71 mtime = times[1].approx_secs()
72 os.utime(path, (atime, mtime))
77 def from_stat_rep(st):
78 result = stat_result()
90 result.st_atime = FSTime.from_timespec(result.st_atime)
91 result.st_mtime = FSTime.from_timespec(result.st_mtime)
92 result.st_ctime = FSTime.from_timespec(result.st_ctime)
97 return stat_result.from_stat_rep(_helpers.stat(path))
101 return stat_result.from_stat_rep(_helpers.fstat(path))
105 return stat_result.from_stat_rep(_helpers.lstat(path))