1 """Enhanced stat operations for bup."""
3 import bup._helpers as _helpers
6 # Class to represent filesystem timestamps. Use integer
7 # nanoseconds on platforms where we have the higher resolution
8 # lstat. Use the native python stat representation (floating
9 # point seconds) otherwise.
12 return self._value.__cmp__(x._value)
14 def to_timespec(self):
15 """Return (s, ns) where ns is always non-negative
16 and t = s + ns / 10e8""" # metadata record rep (and libc rep)
17 s_ns = self.secs_nsecs()
18 if s_ns[0] > 0 or s_ns[1] >= 0:
20 return (s_ns[0] - 1, 10**9 + s_ns[1]) # ns is negative
22 if _helpers.lstat: # Use integer nanoseconds.
27 ts._value = int(secs * 10**9)
31 def from_timespec(timespec):
33 ts._value = timespec[0] * 10**9 + timespec[1]
37 def from_stat_time(stat_time):
38 return FSTime.from_timespec(stat_time)
40 def approx_secs(self):
41 return self._value / 10e8;
44 "Return a (s, ns) pair: -1.5s -> (-1, -10**9 / 2)."
46 return (self._value / 10**9, self._value % 10**9)
47 abs_val = -self._value
48 return (- (abs_val / 10**9), - (abs_val % 10**9))
50 else: # Use python default floating-point seconds.
59 def from_timespec(timespec):
61 ts._value = timespec[0] + (timespec[1] / 10e8)
65 def from_stat_time(stat_time):
70 def approx_secs(self):
74 "Return a (s, ns) pair: -1.5s -> (-1, -5**9)."
75 x = math.modf(self._value)
76 return (x[1], x[0] * 10**9)
79 def lutime(path, times):
80 if _helpers.utimensat:
81 atime = times[0].to_timespec()
82 mtime = times[1].to_timespec()
83 return _helpers.utimensat(_helpers.AT_FDCWD, path, (atime, mtime),
84 _helpers.AT_SYMLINK_NOFOLLOW)
89 def utime(path, times):
90 if _helpers.utimensat:
91 atime = times[0].to_timespec()
92 mtime = times[1].to_timespec()
93 return _helpers.utimensat(_helpers.AT_FDCWD, path, (atime, mtime), 0)
95 atime = times[0].approx_secs()
96 mtime = times[1].approx_secs()
97 os.utime(path, (atime, mtime))
103 def from_stat_rep(st):
104 result = stat_result()
105 if _helpers._have_ns_fs_timestamps:
118 result.st_mode = st.st_mode
119 result.st_ino = st.st_ino
120 result.st_dev = st.st_dev
121 result.st_nlink = st.st_nlink
122 result.st_uid = st.st_uid
123 result.st_gid = st.st_gid
124 result.st_rdev = st.st_rdev
125 result.st_size = st.st_size
126 atime = FSTime.from_stat_time(st.st_atime)
127 mtime = FSTime.from_stat_time(st.st_mtime)
128 ctime = FSTime.from_stat_time(st.st_ctime)
129 result.st_atime = FSTime.from_stat_time(atime)
130 result.st_mtime = FSTime.from_stat_time(mtime)
131 result.st_ctime = FSTime.from_stat_time(ctime)
137 st = _helpers.stat(path)
140 return stat_result.from_stat_rep(st)
145 st = _helpers.fstat(path)
148 return stat_result.from_stat_rep(st)
153 st = _helpers.lstat(path)
156 return stat_result.from_stat_rep(st)