]> arthur.barton.de Git - bup.git/blob - lib/bup/xstat.py
Merge branch 'master' into meta
[bup.git] / lib / bup / xstat.py
1 """Enhanced stat operations for bup."""
2 import os
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 def timespec_to_nsecs((ts_s, ts_ns)):
13     # c.f. _helpers.c: timespec_vals_to_py_ns()
14     if ts_ns < 0 or ts_ns > 999999999:
15         raise Exception('invalid timespec nsec value')
16     return ts_s * 10**9 + ts_ns
17
18
19 def nsecs_to_timespec(ns):
20     """Return (s, ns) where ns is always non-negative
21     and t = s + ns / 10e8""" # metadata record rep (and libc rep)
22     ns = int(ns)
23     return (ns / 10**9, ns % 10**9)
24
25
26 def fstime_floor_secs(ns):
27     """Return largest integer not greater than ns / 10e8."""
28     return int(ns) / 10**9;
29
30
31 def fstime_to_timespec(ns):
32     return nsecs_to_timespec(ns)
33
34
35 if _have_utimensat:
36     def lutime(path, times):
37         atime = nsecs_to_timespec(times[0])
38         mtime = nsecs_to_timespec(times[1])
39         _helpers.utimensat(_helpers.AT_FDCWD, path, (atime, mtime),
40                            _helpers.AT_SYMLINK_NOFOLLOW)
41     def utime(path, times):
42         atime = nsecs_to_timespec(times[0])
43         mtime = nsecs_to_timespec(times[1])
44         _helpers.utimensat(_helpers.AT_FDCWD, path, (atime, mtime), 0)
45 else:
46     def lutime(path, times):
47         return None
48
49     def utime(path, times):
50         atime = fstime_floor_secs(times[0])
51         mtime = fstime_floor_secs(times[1])
52         os.utime(path, (atime, mtime))
53
54
55 class stat_result:
56     @staticmethod
57     def from_xstat_rep(st):
58         result = stat_result()
59         (result.st_mode,
60          result.st_ino,
61          result.st_dev,
62          result.st_nlink,
63          result.st_uid,
64          result.st_gid,
65          result.st_rdev,
66          result.st_size,
67          result.st_atime,
68          result.st_mtime,
69          result.st_ctime) = st
70         result.st_atime = timespec_to_nsecs(result.st_atime)
71         result.st_mtime = timespec_to_nsecs(result.st_mtime)
72         result.st_ctime = timespec_to_nsecs(result.st_ctime)
73         return result
74
75
76 def stat(path):
77     return stat_result.from_xstat_rep(_helpers.stat(path))
78
79
80 def fstat(path):
81     return stat_result.from_xstat_rep(_helpers.fstat(path))
82
83
84 def lstat(path):
85     return stat_result.from_xstat_rep(_helpers.lstat(path))