#ifdef linux /* and likely others */
-#define HAVE_BUP_LSTAT 1
+#define HAVE_BUP_LSTAT 1
static PyObject *bup_lstat(PyObject *self, PyObject *args)
{
int rc;
(long) st.st_ctim.tv_nsec);
}
+#define HAVE_BUP_FSTAT 1
+static PyObject *bup_fstat(PyObject *self, PyObject *args)
+{
+ int rc, fd;
+
+ if (!PyArg_ParseTuple(args, "i", &fd))
+ return NULL;
+
+ struct stat st;
+ rc = fstat(fd, &st);
+ if (rc != 0)
+ return PyErr_SetFromErrno(PyExc_IOError);
+
+ return Py_BuildValue("kkkkkkkk"
+ "(ll)"
+ "(ll)"
+ "(ll)",
+ (unsigned long) st.st_mode,
+ (unsigned long) st.st_ino,
+ (unsigned long) st.st_dev,
+ (unsigned long) st.st_nlink,
+ (unsigned long) st.st_uid,
+ (unsigned long) st.st_gid,
+ (unsigned long) st.st_rdev,
+ (unsigned long) st.st_size,
+ (long) st.st_atime,
+ (long) st.st_atim.tv_nsec,
+ (long) st.st_mtime,
+ (long) st.st_mtim.tv_nsec,
+ (long) st.st_ctime,
+ (long) st.st_ctim.tv_nsec);
+}
+
#endif /* def linux */
#ifdef HAVE_BUP_LSTAT
{ "lstat", bup_lstat, METH_VARARGS,
"Extended version of lstat." },
+#endif
+#ifdef HAVE_BUP_FSTAT
+ { "fstat", bup_fstat, METH_VARARGS,
+ "Extended version of fstat." },
#endif
{ NULL, NULL, 0, NULL }, // sentinel
};
PyModule_AddObject(m, "AT_SYMLINK_NOFOLLOW",
Py_BuildValue("i", AT_SYMLINK_NOFOLLOW));
#endif
+#ifdef HAVE_BUP_LSTAT
+ PyModule_AddObject(m, "_have_ns_fs_timestamps", Py_BuildValue("i", 1));
+#endif
}
class stat_result():
- pass
+
+ @staticmethod
+ def from_stat_rep(st):
+ result = stat_result()
+ if _helpers._have_ns_fs_timestamps:
+ (result.st_mode,
+ result.st_ino,
+ result.st_dev,
+ result.st_nlink,
+ result.st_uid,
+ result.st_gid,
+ result.st_rdev,
+ result.st_size,
+ atime,
+ mtime,
+ ctime) = st
+ else:
+ result.st_mode = st.st_mode
+ result.st_ino = st.st_ino
+ result.st_dev = st.st_dev
+ result.st_nlink = st.st_nlink
+ result.st_uid = st.st_uid
+ result.st_gid = st.st_gid
+ result.st_rdev = st.st_rdev
+ result.st_size = st.st_size
+ atime = FSTime.from_stat_time(st.st_atime)
+ mtime = FSTime.from_stat_time(st.st_mtime)
+ ctime = FSTime.from_stat_time(st.st_ctime)
+ result.st_atime = FSTime.from_stat_time(atime)
+ result.st_mtime = FSTime.from_stat_time(mtime)
+ result.st_ctime = FSTime.from_stat_time(ctime)
+ return result
+
+
+def fstat(path):
+ if _helpers.fstat:
+ st = _helpers.fstat(path)
+ else:
+ st = os.fstat(path)
+ return stat_result.from_stat_rep(st)
def lstat(path):
- result = stat_result()
if _helpers.lstat:
st = _helpers.lstat(path)
- (result.st_mode,
- result.st_ino,
- result.st_dev,
- result.st_nlink,
- result.st_uid,
- result.st_gid,
- result.st_rdev,
- result.st_size,
- atime,
- mtime,
- ctime) = st
else:
st = os.lstat(path)
- result.st_mode = st.st_mode
- result.st_ino = st.st_ino
- result.st_dev = st.st_dev
- result.st_nlink = st.st_nlink
- result.st_uid = st.st_uid
- result.st_gid = st.st_gid
- result.st_rdev = st.st_rdev
- result.st_size = st.st_size
- atime = FSTime.from_stat_time(st.st_atime)
- mtime = FSTime.from_stat_time(st.st_mtime)
- ctime = FSTime.from_stat_time(st.st_ctime)
- result.st_atime = FSTime.from_stat_time(atime)
- result.st_mtime = FSTime.from_stat_time(mtime)
- result.st_ctime = FSTime.from_stat_time(ctime)
- return result
+ return stat_result.from_stat_rep(st)
# hashlib is only available in python 2.5 or higher, but the 'sha' module