glusterfs

Форк
0
/
libcxattr.py 
108 строк · 3.2 Кб
1
#
2
# Copyright (c) 2011-2014 Red Hat, Inc. <http://www.redhat.com>
3
# This file is part of GlusterFS.
4

5
# This file is licensed to you under your choice of the GNU Lesser
6
# General Public License, version 3 or any later version (LGPLv3 or
7
# later), or the GNU General Public License, version 2 (GPLv2), in all
8
# cases as published by the Free Software Foundation.
9
#
10

11
import os
12
import sys
13
from ctypes import CDLL, c_int
14
from py2py3 import bytearray_to_str, gr_create_string_buffer
15
from py2py3 import gr_query_xattr, gr_lsetxattr, gr_lremovexattr
16

17

18
class Xattr(object):
19

20
    """singleton that wraps the extended attributes system
21
       interface for python using ctypes
22

23
       Just implement it to the degree we need it, in particular
24
       - we need just the l*xattr variants, ie. we never want symlinks to be
25
         followed
26
       - don't need size discovery for getxattr, as we always know the exact
27
         sizes we expect
28
    """
29

30
    if sys.hexversion >= 0x02060000:
31
        from ctypes import DEFAULT_MODE
32
        libc = CDLL("libc.so.6", DEFAULT_MODE, None, True)
33
    else:
34
        libc = CDLL("libc.so.6")
35

36
    @classmethod
37
    def geterrno(cls):
38
        if sys.hexversion >= 0x02060000:
39
            from ctypes import get_errno
40
            return get_errno()
41
        # breaks on NetBSD
42
        return c_int.in_dll(cls.libc, 'errno').value
43

44
    @classmethod
45
    def raise_oserr(cls):
46
        errn = cls.geterrno()
47
        raise OSError(errn, os.strerror(errn))
48

49
    @classmethod
50
    def _query_xattr(cls, path, siz, syscall, *a):
51
        if siz:
52
            buf = gr_create_string_buffer(siz)
53
        else:
54
            buf = None
55
        ret = getattr(cls.libc, syscall)(*((path,) + a + (buf, siz)))
56
        if ret == -1:
57
            cls.raise_oserr()
58
        if siz:
59
            # py2 and py3 compatibility. Convert bytes array
60
            # to string
61
            result = bytearray_to_str(buf.raw)
62
            return result[:ret]
63
        else:
64
            return ret
65

66
    @classmethod
67
    def lgetxattr(cls, path, attr, siz=0):
68
        return gr_query_xattr(cls, path, siz, 'lgetxattr', attr)
69

70
    @classmethod
71
    def lgetxattr_buf(cls, path, attr):
72
        """lgetxattr variant with size discovery"""
73
        size = cls.lgetxattr(path, attr)
74
        if size == -1:
75
            cls.raise_oserr()
76
        if size == 0:
77
            return ''
78
        return cls.lgetxattr(path, attr, size)
79

80
    @classmethod
81
    def llistxattr(cls, path, siz=0):
82
        ret = gr_query_xattr(cls, path, siz, 'llistxattr')
83
        if isinstance(ret, str):
84
            ret = ret.strip('\0')
85
            ret = ret.split('\0') if ret else []
86
        return ret
87

88
    @classmethod
89
    def lsetxattr(cls, path, attr, val):
90
        ret = gr_lsetxattr(cls, path, attr, val)
91
        if ret == -1:
92
            cls.raise_oserr()
93

94
    @classmethod
95
    def lremovexattr(cls, path, attr):
96
        ret = gr_lremovexattr(cls, path, attr)
97
        if ret == -1:
98
            cls.raise_oserr()
99

100
    @classmethod
101
    def llistxattr_buf(cls, path):
102
        """listxattr variant with size discovery"""
103
        size = cls.llistxattr(path)
104
        if size == -1:
105
            cls.raise_oserr()
106
        if size == 0:
107
            return []
108
        return cls.llistxattr(path, size)
109

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.