1 """Enhanced stat operations for bup."""
3 from __future__ import absolute_import
6 from bup import _helpers
9 _bup_utimensat = _helpers.bup_utimensat
10 except AttributeError as e:
11 _bup_utimensat = False
14 _bup_utimes = _helpers.bup_utimes
15 except AttributeError as e:
19 _bup_lutimes = _helpers.bup_lutimes
20 except AttributeError as e:
24 def timespec_to_nsecs((ts_s, ts_ns)):
25 return ts_s * 10**9 + ts_ns
28 def nsecs_to_timespec(ns):
29 """Return (s, ns) where ns is always non-negative
30 and t = s + ns / 10e8""" # metadata record rep
32 return (ns / 10**9, ns % 10**9)
35 def nsecs_to_timeval(ns):
36 """Return (s, us) where ns is always non-negative
37 and t = s + us / 10e5"""
39 return (ns / 10**9, (ns % 10**9) / 1000)
42 def fstime_floor_secs(ns):
43 """Return largest integer not greater than ns / 10e8."""
44 return int(ns) / 10**9;
47 def fstime_to_timespec(ns):
48 return nsecs_to_timespec(ns)
51 def fstime_to_sec_str(fstime):
52 (s, ns) = fstime_to_timespec(fstime)
58 return '%d.%09d' % (s, ns)
62 def utime(path, times):
63 """Times must be provided as (atime_ns, mtime_ns)."""
64 atime = nsecs_to_timespec(times[0])
65 mtime = nsecs_to_timespec(times[1])
66 _bup_utimensat(_helpers.AT_FDCWD, path, (atime, mtime), 0)
67 def lutime(path, times):
68 """Times must be provided as (atime_ns, mtime_ns)."""
69 atime = nsecs_to_timespec(times[0])
70 mtime = nsecs_to_timespec(times[1])
71 _bup_utimensat(_helpers.AT_FDCWD, path, (atime, mtime),
72 _helpers.AT_SYMLINK_NOFOLLOW)
73 else: # Must have these if utimensat isn't available.
74 def utime(path, times):
75 """Times must be provided as (atime_ns, mtime_ns)."""
76 atime = nsecs_to_timeval(times[0])
77 mtime = nsecs_to_timeval(times[1])
78 _bup_utimes(path, (atime, mtime))
79 def lutime(path, times):
80 """Times must be provided as (atime_ns, mtime_ns)."""
81 atime = nsecs_to_timeval(times[0])
82 mtime = nsecs_to_timeval(times[1])
83 _bup_lutimes(path, (atime, mtime))
85 _cygwin_sys = sys.platform.startswith('cygwin')
87 def _fix_cygwin_id(id):
96 def from_xstat_rep(st):
98 result = stat_result()
109 result.st_ctime) = st
110 # Inlined timespec_to_nsecs after profiling
111 result.st_atime = result.st_atime[0] * 10**9 + result.st_atime[1]
112 result.st_mtime = result.st_mtime[0] * 10**9 + result.st_mtime[1]
113 result.st_ctime = result.st_ctime[0] * 10**9 + result.st_ctime[1]
115 result.st_uid = _fix_cygwin_id(result.st_uid)
116 result.st_gid = _fix_cygwin_id(result.st_gid)
121 return stat_result.from_xstat_rep(_helpers.stat(path))
125 return stat_result.from_xstat_rep(_helpers.fstat(path))
129 return stat_result.from_xstat_rep(_helpers.lstat(path))
134 # FIXME: Other types?
135 if pystat.S_ISREG(mode):
137 elif pystat.S_ISDIR(mode):
139 elif pystat.S_ISCHR(mode):
141 elif pystat.S_ISBLK(mode):
143 elif pystat.S_ISFIFO(mode):
145 elif pystat.S_ISLNK(mode):
147 elif pystat.S_ISSOCK(mode):
152 result += 'r' if (mode & pystat.S_IRUSR) else '-'
153 result += 'w' if (mode & pystat.S_IWUSR) else '-'
154 result += 'x' if (mode & pystat.S_IXUSR) else '-'
155 result += 'r' if (mode & pystat.S_IRGRP) else '-'
156 result += 'w' if (mode & pystat.S_IWGRP) else '-'
157 result += 'x' if (mode & pystat.S_IXGRP) else '-'
158 result += 'r' if (mode & pystat.S_IROTH) else '-'
159 result += 'w' if (mode & pystat.S_IWOTH) else '-'
160 result += 'x' if (mode & pystat.S_IXOTH) else '-'
164 def classification_str(mode, include_exec):
165 if pystat.S_ISREG(mode):
167 and (pystat.S_IMODE(mode) \
168 & (pystat.S_IXUSR | pystat.S_IXGRP | pystat.S_IXOTH)):
172 elif pystat.S_ISDIR(mode):
174 elif pystat.S_ISLNK(mode):
176 elif pystat.S_ISFIFO(mode):
178 elif pystat.S_ISSOCK(mode):