From 8cce7dad8f8f23f19023d9b68b072ec8026ae04d Mon Sep 17 00:00:00 2001 From: Rishabh Dave Date: Sat, 13 Jul 2019 11:29:17 +0530 Subject: [PATCH] pybind/cephfs: add method that stats symlinks without following Add a new Python binding equivalent to lstat so that information about the symlink itself can be also obtained, along with other type of files. Signed-off-by: Rishabh Dave --- src/pybind/cephfs/cephfs.pyx | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/pybind/cephfs/cephfs.pyx b/src/pybind/cephfs/cephfs.pyx index cbe31e1d913..40b724f4321 100644 --- a/src/pybind/cephfs/cephfs.pyx +++ b/src/pybind/cephfs/cephfs.pyx @@ -21,6 +21,7 @@ if sys.version_info[0] < 3: else: str_type = str +cdef int AT_SYMLINK_NOFOLLOW = 0x100 cdef extern from "Python.h": # These are in cpython/string.pxd, but use "object" types instead of @@ -1095,7 +1096,7 @@ cdef class LibCephFS(object): raise make_ex(ret, "error in setxattr") - def stat(self, path): + def stat(self, path, follow_symlink=True): """ Get a file's extended statistics and attributes. @@ -1108,9 +1109,15 @@ cdef class LibCephFS(object): char* _path = path statx stx - with nogil: - # FIXME: replace magic number with CEPH_STATX_BASIC_STATS - ret = ceph_statx(self.cluster, _path, &stx, 0x7ffu, 0) + if follow_symlink: + with nogil: + # FIXME: replace magic number with CEPH_STATX_BASIC_STATS + ret = ceph_statx(self.cluster, _path, &stx, 0x7ffu, 0) + else: + with nogil: + ret = ceph_statx(self.cluster, _path, &stx, 0x7ffu, + AT_SYMLINK_NOFOLLOW) + if ret < 0: raise make_ex(ret, "error in stat: {}".format(path.decode('utf-8'))) return StatResult(st_dev=stx.stx_dev, st_ino=stx.stx_ino, @@ -1123,6 +1130,16 @@ cdef class LibCephFS(object): st_mtime=datetime.fromtimestamp(stx.stx_mtime.tv_sec), st_ctime=datetime.fromtimestamp(stx.stx_ctime.tv_sec)) + def lstat(self, path): + """ + Get a file's extended statistics and attributes. When file's a + symbolic link, return the informaion of the link itself rather + than that of the file it points too. + + :param path: the file or directory to get the statistics of. + """ + return self.stat(path, follow_symlink=False) + def fstat(self, fd): """ Get an open file's extended statistics and attributes. -- 2.39.5