Extended Attributes

以名称-值对形式将任意元数据与文件 i 节点关联起来的技术。

EA 可用于实现 ACL 和文件能力。【还可以利用 EA 去记录文件的版本号,与文件的 MIME 类型/字符集有关的信息或指向图符的指针】

在 shell 中,通过 setfattr 和 getfattr 命令来设置和查看文件的 EA。

相关系统调用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <sys/xattr.h>

/* Set the attribute NAME of the file pointed to by PATH to VALUE (which
   is SIZE bytes long).  Return 0 on success, -1 for errors.  */
extern int setxattr (const char *__path, const char *__name,
             const void *__value, size_t __size, int __flags)
    __THROW;

/* Set the attribute NAME of the file pointed to by PATH to VALUE (which is
   SIZE bytes long), not following symlinks for the last pathname component.
   Return 0 on success, -1 for errors.  */
extern int lsetxattr (const char *__path, const char *__name,
              const void *__value, size_t __size, int __flags)
    __THROW;

/* Set the attribute NAME of the file descriptor FD to VALUE (which is SIZE
   bytes long).  Return 0 on success, -1 for errors.  */
extern int fsetxattr (int __fd, const char *__name, const void *__value,
              size_t __size, int __flags) __THROW;

/* Get the attribute NAME of the file pointed to by PATH to VALUE (which is
   SIZE bytes long).  Return 0 on success, -1 for errors.  */
extern ssize_t getxattr (const char *__path, const char *__name,
             void *__value, size_t __size) __THROW;

/* Get the attribute NAME of the file pointed to by PATH to VALUE (which is
   SIZE bytes long), not following symlinks for the last pathname component.
   Return 0 on success, -1 for errors.  */
extern ssize_t lgetxattr (const char *__path, const char *__name,
              void *__value, size_t __size) __THROW;

/* Get the attribute NAME of the file descriptor FD to VALUE (which is SIZE
   bytes long).  Return 0 on success, -1 for errors.  */
extern ssize_t fgetxattr (int __fd, const char *__name, void *__value,
              size_t __size) __THROW;
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <sys/xattr.h>
#include "tlpi_hdr.h"

#define XATTR_SIZE 10000

static void usageError(char *progName)
{
    fprintf(stderr, "Usage: %s [-x] file...\n", progName);
    exit(EXIT_FAILURE);
}

int main(int argc, char *argv[])
{
    char list[XATTR_SIZE], value[XATTR_SIZE];
    ssize_t listLen, valueLen;
    int ns, j, k, opt;
    boolean hexDisplay;

    hexDisplay = 0;
    while ((opt = getopt(argc, argv, "x")) != -1)
    {
        switch (opt)
        {
        case 'x':
            hexDisplay = 1;
            break;
        case '?':
            usageError(argv[0]);
        }
    }

    if (optind >= argc)
        usageError(argv[0]);

    for (j = optind; j < argc; j++)
    {
        listLen = listxattr(argv[j], list, XATTR_SIZE);
        if (listLen == -1)
            errExit("listxattr");

        printf("%s:\n", argv[j]);

        /* Loop through all EA names, displaying name + value */

        for (ns = 0; ns < listLen; ns += strlen(&list[ns]) + 1)
        {
            printf("        name=%s; ", &list[ns]);

            valueLen = getxattr(argv[j], &list[ns], value, XATTR_SIZE);
            if (valueLen == -1)
            {
                printf("couldn't get value");
            }
            else if (!hexDisplay)
            {
                printf("value=%.*s", (int)valueLen, value);
            }
            else
            {
                printf("value=");
                for (k = 0; k < valueLen; k++)
                    printf("%02x ", (unsigned char)value[k]);
            }

            printf("\n");
        }

        printf("\n");
    }

    exit(EXIT_SUCCESS);
}
Licensed under CC BY-NC-SA 4.0
Get Things Done
Built with Hugo
Theme Stack designed by Jimmy