listxattr(2) System Calls Manual listxattr(2) listxattr, llistxattr, flistxattr - LIBRARY Standard C library (libc, -lc) #include ssize_t listxattr(const char *path, char *_Nullable list, size_t size); ssize_t llistxattr(const char *path, char *_Nullable list, size_t size); ssize_t flistxattr(int fd, char *_Nullable list, size_t size); : inode (, , ..). , inode (, stat(2)). xattr(7). listxattr() , path . list , size ( ). ( null) . , , . list. llistxattr() listxattr(), , , , , . flistxattr() listxattr(), , , fd ( open(2)), path. name , null. ; , inode. size , ( list). , ( , , , ). The list of names is returned as an unordered array of null-terminated character strings (attribute names are separated by null bytes ('\0')), like this: user.name1\0system.name1\0user.name2\0 , ACL POSIX , : system.posix_acl_access\0system.posix_acl_default\0 On success, a nonnegative number is returned indicating the size of the extended attribute name list. On failure, -1 is returned and errno is set to indicate the error. E2BIG ; . , , XFS. . ENOTSUP . ERANGE size list . , stat(2). Linux. Linux 2.4, glibc 2.3. xattr(7), VFS 64 , listxattr(). , , , . listxattr() getxattr(2). , , . . . , , , listxattr(). , (, ) ERANGE. getxattr(2) . , -. $ touch /tmp/foo $ setfattr -n user.fred -v chocolate /tmp/foo $ setfattr -n user.frieda -v bar /tmp/foo $ setfattr -n user.empty /tmp/foo $ ./listxattr /tmp/foo user.fred: chocolate user.frieda: bar user.empty: < > (listxattr.c) #include #include #include #include int main(int argc, char *argv[]) { char *buf, *key, *val; ssize_t buflen, keylen, vallen; if (argc != 2) { fprintf(stderr, "Usage: %s path\n", argv[0]); exit(EXIT_FAILURE); } /* * Determine the length of the buffer needed. */ buflen = listxattr(argv[1], NULL, 0); if (buflen == -1) { perror("listxattr"); exit(EXIT_FAILURE); } if (buflen == 0) { printf("%s has no attributes.\n", argv[1]); exit(EXIT_SUCCESS); } /* * Allocate the buffer. */ buf = malloc(buflen); if (buf == NULL) { perror("malloc"); exit(EXIT_FAILURE); } /* * Copy the list of attribute keys to the buffer. */ buflen = listxattr(argv[1], buf, buflen); if (buflen == -1) { perror("listxattr"); exit(EXIT_FAILURE); } /* * Loop over the list of zero terminated strings with the * attribute keys. Use the remaining buffer length to determine * the end of the list. */ key = buf; while (buflen > 0) { /* * Output attribute key. */ printf("%s: ", key); /* * Determine length of the value. */ vallen = getxattr(argv[1], key, NULL, 0); if (vallen == -1) perror("getxattr"); if (vallen > 0) { /* * Allocate value buffer. * One extra byte is needed to append 0x00. */ val = malloc(vallen + 1); if (val == NULL) { perror("malloc"); exit(EXIT_FAILURE); } /* * Copy value to buffer. */ vallen = getxattr(argv[1], key, val, vallen); if (vallen == -1) { perror("getxattr"); } else { /* * Output attribute value. */ val[vallen] = 0; printf("%s", val); } free(val); } else if (vallen == 0) { printf(""); } printf("\n"); /* * Forward to next attribute key. */ keylen = strlen(key) + 1; buflen -= keylen; key += keylen; } free(buf); exit(EXIT_SUCCESS); } . getfattr(1), setfattr(1), getxattr(2), open(2), removexattr(2), setxattr(2), stat(2), symlink(7), xattr(7) Azamat Hackimov , Dmitriy S. Seregin , Yuri Kozlov ; GNU 3 , . . , , . Linux man-pages 6.06 31 2023 . listxattr(2)