]> arthur.barton.de Git - bup.git/blob - lib/bup/xstat.py
metadata/xstat: fix a bunch of CodingStyle issues.
[bup.git] / lib / bup / xstat.py
1 """Enhanced stat operations for bup."""
2 import os, math
3 from bup import _helpers
4
5
6 try:
7     _have_utimensat = _helpers.utimensat
8 except AttributeError, e:
9     _have_utimensat = False
10
11
12 class FSTime():
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.
17
18     def __cmp__(self, x):
19         return self._value.__cmp__(x._value)
20
21     def to_timespec(self):
22         """Return (s, ns) where ns is always non-negative
23         and t = s + ns / 10e8""" # metadata record rep (and libc rep)
24         s_ns = self.secs_nsecs()
25         if s_ns[0] > 0 or s_ns[1] >= 0:
26             return s_ns
27         return (s_ns[0] - 1, 10**9 + s_ns[1]) # ns is negative
28
29     @staticmethod
30     def from_secs(secs):
31         ts = FSTime()
32         ts._value = int(secs * 10**9)
33         return ts
34
35     @staticmethod
36     def from_timespec(timespec):
37         ts = FSTime()
38         ts._value = timespec[0] * 10**9 + timespec[1]
39         return ts
40
41     def approx_secs(self):
42         return self._value / 10e8;
43
44     def secs_nsecs(self):
45         "Return a (s, ns) pair: -1.5s -> (-1, -10**9 / 2)."
46         if self._value >= 0:
47             return (self._value / 10**9, self._value % 10**9)
48         abs_val = -self._value
49         return (- (abs_val / 10**9), - (abs_val % 10**9))
50
51     if _helpers._have_ns_fs_timestamps: # Use integer nanoseconds.
52         @staticmethod
53         def from_stat_time(stat_time):
54             return FSTime.from_timespec(stat_time)
55     else: # Use python default floating-point seconds.
56         @staticmethod
57         def from_stat_time(stat_time):
58             ts = FSTime()
59             x = math.modf(stat_time)
60             ts._value = int(x[1]) + int(x[0] * 10**9)
61             return ts
62
63
64 if _have_utimensat:
65     def lutime(path, times):
66         atime = times[0].to_timespec()
67         mtime = times[1].to_timespec()
68         return _helpers.utimensat(_helpers.AT_FDCWD, path, (atime, mtime),
69                                   _helpers.AT_SYMLINK_NOFOLLOW)
70     def utime(path, times):
71         atime = times[0].to_timespec()
72         mtime = times[1].to_timespec()
73         return _helpers.utimensat(_helpers.AT_FDCWD, path, (atime, mtime), 0)
74 else:
75     def lutime(path, times):
76         return None
77
78     def utime(path, times):
79         atime = times[0].approx_secs()
80         mtime = times[1].approx_secs()
81         os.utime(path, (atime, mtime))
82
83
84 class stat_result():
85     @staticmethod
86     def from_stat_rep(st):
87         result = stat_result()
88         if _helpers._have_ns_fs_timestamps:
89             (result.st_mode,
90              result.st_ino,
91              result.st_dev,
92              result.st_nlink,
93              result.st_uid,
94              result.st_gid,
95              result.st_rdev,
96              result.st_size,
97              atime,
98              mtime,
99              ctime) = st
100         else:
101             result.st_mode = st.st_mode
102             result.st_ino = st.st_ino
103             result.st_dev = st.st_dev
104             result.st_nlink = st.st_nlink
105             result.st_uid = st.st_uid
106             result.st_gid = st.st_gid
107             result.st_rdev = st.st_rdev
108             result.st_size = st.st_size
109             atime = st.st_atime
110             mtime = st.st_mtime
111             ctime = st.st_ctime
112         result.st_atime = FSTime.from_stat_time(atime)
113         result.st_mtime = FSTime.from_stat_time(mtime)
114         result.st_ctime = FSTime.from_stat_time(ctime)
115         return result
116
117
118 try:
119     _stat = _helpers.stat
120 except AttributeError, e:
121     _stat = os.stat
122
123 def stat(path):
124     return stat_result.from_stat_rep(_stat(path))
125
126
127 try:
128     _fstat = _helpers.fstat
129 except AttributeError, e:
130     _fstat = os.fstat
131
132 def fstat(path):
133     return stat_result.from_stat_rep(_fstat(path))
134
135
136 try:
137     _lstat = _helpers.lstat
138 except AttributeError, e:
139     _lstat = os.lstat
140
141 def lstat(path):
142     return stat_result.from_stat_rep(_lstat(path))