| .\" Copyright (C) Andreas Gruenbacher, February 2001 |
| .\" Copyright (C) Silicon Graphics Inc, September 2001 |
| .\" Copyright (C) 2015 Heinrich Schuchardt <xypron.glpk@gmx.de> |
| .\" |
| .\" %%%LICENSE_START(GPLv2+_DOC_FULL) |
| .\" This is free documentation; you can redistribute it and/or |
| .\" modify it under the terms of the GNU General Public License as |
| .\" published by the Free Software Foundation; either version 2 of |
| .\" the License, or (at your option) any later version. |
| .\" |
| .\" The GNU General Public License's references to "object code" |
| .\" and "executables" are to be interpreted as the output of any |
| .\" document formatting or typesetting system, including |
| .\" intermediate and printed output. |
| .\" |
| .\" This manual is distributed in the hope that it will be useful, |
| .\" but WITHOUT ANY WARRANTY; without even the implied warranty of |
| .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| .\" GNU General Public License for more details. |
| .\" |
| .\" You should have received a copy of the GNU General Public |
| .\" License along with this manual; if not, see |
| .\" <http://www.gnu.org/licenses/>. |
| .\" %%%LICENSE_END |
| .\" |
| .TH LISTXATTR 2 2021-03-22 "Linux" "Linux Programmer's Manual" |
| .SH NAME |
| listxattr, llistxattr, flistxattr \- list extended attribute names |
| .SH SYNOPSIS |
| .fam C |
| .nf |
| .B #include <sys/xattr.h> |
| .PP |
| .BI "ssize_t listxattr(const char *" path ", char *" list \ |
| ", size_t " size ); |
| .BI "ssize_t llistxattr(const char *" path ", char *" list \ |
| ", size_t " size ); |
| .BI "ssize_t flistxattr(int " fd ", char *" list ", size_t " size ); |
| .fi |
| .fam T |
| .SH DESCRIPTION |
| Extended attributes are |
| .IR name : value |
| pairs associated with inodes (files, directories, symbolic links, etc.). |
| They are extensions to the normal attributes which are associated |
| with all inodes in the system (i.e., the |
| .BR stat (2) |
| data). |
| A complete overview of extended attributes concepts can be found in |
| .BR xattr (7). |
| .PP |
| .BR listxattr () |
| retrieves the list |
| of extended attribute names associated with the given |
| .I path |
| in the filesystem. |
| The retrieved list is placed in |
| .IR list , |
| a caller-allocated buffer whose size (in bytes) is specified in the argument |
| .IR size . |
| The list is the set of (null-terminated) names, one after the other. |
| Names of extended attributes to which the calling process does not |
| have access may be omitted from the list. |
| The length of the attribute name |
| .I list |
| is returned. |
| .PP |
| .BR llistxattr () |
| is identical to |
| .BR listxattr (), |
| except in the case of a symbolic link, where the list of names of |
| extended attributes associated with the link itself is retrieved, |
| not the file that it refers to. |
| .PP |
| .BR flistxattr () |
| is identical to |
| .BR listxattr (), |
| only the open file referred to by |
| .I fd |
| (as returned by |
| .BR open (2)) |
| is interrogated in place of |
| .IR path . |
| .PP |
| A single extended attribute |
| .I name |
| is a null-terminated string. |
| The name includes a namespace prefix; there may be several, disjoint |
| namespaces associated with an individual inode. |
| .PP |
| If |
| .I size |
| is specified as zero, these calls return the current size of the |
| list of extended attribute names (and leave |
| .I list |
| unchanged). |
| This can be used to determine the size of the buffer that |
| should be supplied in a subsequent call. |
| (But, bear in mind that there is a possibility that the |
| set of extended attributes may change between the two calls, |
| so that it is still necessary to check the return status |
| from the second call.) |
| .SS Example |
| The |
| .I list |
| of names is returned as an unordered array of null-terminated character |
| strings (attribute names are separated by null bytes (\(aq\e0\(aq)), like this: |
| .PP |
| .in +4n |
| .EX |
| user.name1\e0system.name1\e0user.name2\e0 |
| .EE |
| .in |
| .PP |
| Filesystems that implement POSIX ACLs using |
| extended attributes might return a |
| .I list |
| like this: |
| .PP |
| .in +4n |
| .EX |
| system.posix_acl_access\e0system.posix_acl_default\e0 |
| .EE |
| .in |
| .SH RETURN VALUE |
| On success, a nonnegative number is returned indicating the size of the |
| extended attribute name list. |
| On failure, \-1 is returned and |
| .I errno |
| is set to indicate the error. |
| .SH ERRORS |
| .TP |
| .B E2BIG |
| The size of the list of extended attribute names is larger than the maximum |
| size allowed; the list cannot be retrieved. |
| This can happen on filesystems that support an unlimited number of |
| extended attributes per file such as XFS, for example. |
| See BUGS. |
| .TP |
| .B ENOTSUP |
| Extended attributes are not supported by the filesystem, or are disabled. |
| .TP |
| .B ERANGE |
| The |
| .I size |
| of the |
| .I list |
| buffer is too small to hold the result. |
| .PP |
| In addition, the errors documented in |
| .BR stat (2) |
| can also occur. |
| .SH VERSIONS |
| These system calls have been available on Linux since kernel 2.4; |
| glibc support is provided since version 2.3. |
| .SH CONFORMING TO |
| These system calls are Linux-specific. |
| .\" .SH AUTHORS |
| .\" Andreas Gruenbacher, |
| .\" .RI < a.gruenbacher@computer.org > |
| .\" and the SGI XFS development team, |
| .\" .RI < linux-xfs@oss.sgi.com >. |
| .\" Please send any bug reports or comments to these addresses. |
| .SH BUGS |
| .\" The xattr(7) page refers to this text: |
| As noted in |
| .BR xattr (7), |
| the VFS imposes a limit of 64\ kB on the size of the extended |
| attribute name list returned by |
| .BR listxattr (7). |
| If the total size of attribute names attached to a file exceeds this limit, |
| it is no longer possible to retrieve the list of attribute names. |
| .SH EXAMPLES |
| The following program demonstrates the usage of |
| .BR listxattr () |
| and |
| .BR getxattr (2). |
| For the file whose pathname is provided as a command-line argument, |
| it lists all extended file attributes and their values. |
| .PP |
| To keep the code simple, the program assumes that attribute keys and |
| values are constant during the execution of the program. |
| A production program should expect and handle changes during |
| execution of the program. |
| For example, |
| the number of bytes required for attribute keys |
| might increase between the two calls to |
| .BR listxattr (). |
| An application could handle this possibility using |
| a loop that retries the call |
| (perhaps up to a predetermined maximum number of attempts) |
| with a larger buffer each time it fails with the error |
| .BR ERANGE . |
| Calls to |
| .BR getxattr (2) |
| could be handled similarly. |
| .PP |
| The following output was recorded by first creating a file, setting |
| some extended file attributes, |
| and then listing the attributes with the example program. |
| .SS Example output |
| .in +4n |
| .EX |
| $ \fBtouch /tmp/foo\fP |
| $ \fBsetfattr \-n user.fred \-v chocolate /tmp/foo\fP |
| $ \fBsetfattr \-n user.frieda \-v bar /tmp/foo\fP |
| $ \fBsetfattr \-n user.empty /tmp/foo\fP |
| $ \fB./listxattr /tmp/foo\fP |
| user.fred: chocolate |
| user.frieda: bar |
| user.empty: <no value> |
| .EE |
| .in |
| .SS Program source (listxattr.c) |
| .EX |
| #include <malloc.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <sys/types.h> |
| #include <sys/xattr.h> |
| |
| int |
| main(int argc, char *argv[]) |
| { |
| ssize_t buflen, keylen, vallen; |
| char *buf, *key, *val; |
| |
| if (argc != 2) { |
| fprintf(stderr, "Usage: %s path\en", 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.\en", 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("<no value>"); |
| |
| printf("\en"); |
| |
| /* |
| * Forward to next attribute key. |
| */ |
| keylen = strlen(key) + 1; |
| buflen \-= keylen; |
| key += keylen; |
| } |
| |
| free(buf); |
| exit(EXIT_SUCCESS); |
| } |
| .EE |
| .SH SEE ALSO |
| .BR getfattr (1), |
| .BR setfattr (1), |
| .BR getxattr (2), |
| .BR open (2), |
| .BR removexattr (2), |
| .BR setxattr (2), |
| .BR stat (2), |
| .BR symlink (7), |
| .BR xattr (7) |