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