---
name: "attr_list"
section: "3"
platform: "linux"
package: "attr"
version: "2.6.0-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/attr_list"
---

# attr\_list(3)

list the names of the user attributes of a filesystem object

## NAME

attr\_list, attr\_listf - list the names of the user attributes of a filesystem object

## C SYNOPSIS

```
#include <attr/attributes.h>

int attr_list (const char ∗path, char ∗buffer,
               const int buffersize, int flags,
               attrlist_cursor_t ∗cursor);
```

**int attr\_listf (int fd, char ∗buffer,**                  **const int buffersize, int flags,**                 **attrlist\_cursor\_t ∗cursor);**

## DESCRIPTION

The **attr\_list** and **attr\_listf** functions provide a way to list the existing attributes of a filesystem object.

*Path* points to a path name for a filesystem object, and *fd* refers to the file descriptor associated with a file. The *buffer* will be filled with a structure describing at least a portion of the attributes associated with the given filesystem object. *Buffer* will be overwritten with an ***attrlist\_t*** structure containing a list of the attributes associated with that filesystem object, up to a maximum of *buffersize* bytes. The *buffer* must be sufficiently large to hold the appropriate data structures plus at least one maximally sized attribute name, but cannot be more than ATTR\_MAX\_VALUELEN (currently 64KB) bytes in length.

The contents of an ***attrlist\_t*** structure include the following members:

```
int32_t al_count; /∗ number of entries in attrlist ∗/
int32_t al_more; /∗ T/F: more attrs (do syscall again) ∗/
int32_t al_offset[1]; /∗ byte offsets of attrs [var-sized] ∗/
```

The *al\_count* field shows the number of attributes represented in this buffer, which is also the number of elements in the *al\_offset* array. The *al\_more* field will be non-zero if another **attr\_list** call would result in more attributes. The *al\_offset* array contains the byte offset within the *buffer* of the structure describing each of the attributes, an ***attrlist\_ent\_t*** structure. The ***ATTR\_ENTRY(buffer, index)*** macro will help with decoding the list. It takes a pointer to the *buffer* and an *index* into the *al\_offset* array and returns a pointer to the corresponding ***attrlist\_ent\_t*** structure.

The contents of an ***attrlist\_ent\_t*** structure include the following members:

```
uint32_t a_valuelen; /∗ number bytes in value of attr ∗/
char a_name[]; /∗ attr name (NULL terminated) ∗/
```

The *a\_valuelen* field shows the size in bytes of the value associated with the attribute whose name is stored in the *a\_name* field. The name is a NULL terminated string.

Note that the value of the attribute cannot be obtained through this interface, the **attr\_get** call should be used to get the value. The **attr\_list** interface tells the calling process how large of a buffer it must have in order to get the attribute's value.

The *flags* argument can contain the following symbols bitwise OR'ed together:

- ATTR\_ROOT

  List the attributes that are in the **root** address space, not in the **user** address space. (limited to use by super-user only)

- ATTR\_DONTFOLLOW

  Do not follow symbolic links when resolving a *path* on an **attr\_list** function call. The default is to follow symbolic links.

The *cursor* argument is a pointer to an opaque data structure that the kernel uses to track the calling process's position in the attribute list. The only valid operations on a *cursor* are to pass it into an **attr\_list** function call or to zero it out. It should be zero'ed out before the first **attr\_list** call. Note that multi-threaded applications may keep more than one *cursor* in order to serve multiple contexts, ie: the **attr\_list** call is "thread-safe".

**attr\_list** will fail if one or more of the following are true:

- \[ENOENT\]

  The named file does not exist.

- \[EPERM\]

  The effective user ID does not match the owner of the file and the effective user ID is not super-user.

- \[ENOTDIR\]

  A component of the path prefix is not a directory.

- \[EACCES\]

  Search permission is denied on a component of the path prefix.

- \[EINVAL\]

  A bit was set in the *flag* argument that is not defined for this system call, or the buffer was too small or too large.

- \[EFAULT\]

  Either *Path* or *buffer* points outside the allocated address space of the process, or *buffer* or *bufsize* are not 32bit aligned.

- \[ELOOP\]

  A path name lookup involved too many symbolic links.

- \[ENAMETOOLONG\]

  The length of *path* exceeds {*MAXPATHLEN*}, or a pathname component is longer than {*MAXNAMELEN*}.

- \[ENOATTR\]

  *attribute* does not exist for this file.

**attr\_listf** will fail if:

- \[EINVAL\]

  A bit was set in the *flag* argument that is not defined for this system call, or *fd* refers to a socket, not a file, or the buffer was too small or too large.

- \[EFAULT\]

  Either *Path* or *buffer* points outside the allocated address space of the process, or *buffer* or *bufsize* are not 32bit aligned.

- \[EBADF\]

  *Fd* does not refer to a valid descriptor.

## DIAGNOSTICS

Upon successful completion, a value of 0 is returned. Otherwise, a value of -1 is returned and *errno* is set to indicate the error.

## SEE ALSO

[**attr**(1)](/attr/1.md), [**attr\_multi**(3)](/attr_multi/3.md), [**attr\_remove**(3)](/attr_remove/3.md), [**attr\_set**(3)](/attr_set/3.md)
