406 lines
12 KiB
Groff
406 lines
12 KiB
Groff
.\" Copyright (c) 2013 Apple Computer, Inc. All rights reserved.
|
|
.\"
|
|
.\" The contents of this file constitute Original Code as defined in and
|
|
.\" are subject to the Apple Public Source License Version 1.1 (the
|
|
.\" "License"). You may not use this file except in compliance with the
|
|
.\" License. Please obtain a copy of the License at
|
|
.\" http://www.apple.com/publicsource and read it before using this file.
|
|
.\"
|
|
.\" This Original Code and all software distributed under the License are
|
|
.\" distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
|
.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
|
.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
|
.\" FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
|
|
.\" License for the specific language governing rights and limitations
|
|
.\" under the License.
|
|
.\"
|
|
.\" @(#)getattrlistbulk.2
|
|
.
|
|
.Dd November 15, 2013
|
|
.Dt GETATTRLISTBULK 2
|
|
.Os Darwin
|
|
.Sh NAME
|
|
.Nm getattrlistbulk
|
|
.Nd get file system attributes for multiple directory entries
|
|
.Sh SYNOPSIS
|
|
.Fd #include <sys/attr.h>
|
|
.Fd #include <unistd.h>
|
|
.Pp
|
|
.Ft int
|
|
.Fn getattrlistbulk "int dirfd" "struct attrlist * attrList" "void * attrBuf" "size_t attrBufSize" "uint64_t options"
|
|
.
|
|
.
|
|
.Sh DESCRIPTION
|
|
The
|
|
.Fn getattrlistbulk
|
|
function iterates over the items in a directory and returns information about
|
|
each directory entry like
|
|
.Xr getattrlist 2 .
|
|
Note: when
|
|
.Fn getattrlistbulk
|
|
returns information about a symbolic link, the information returned is about the link itself, not the target of the link.
|
|
The order of the directory entries (and their associated metadata) vended by
|
|
.Fn getattrlistbulk
|
|
is not specified. Some file systems may return entries in lexicographic sort order and others may not.
|
|
.Pp
|
|
The function reads directory entries from the directory referenced by the file
|
|
descriptor
|
|
.Fa dirfd .
|
|
The
|
|
.Fa attrList
|
|
parameter determines what attributes are returned for each entry.
|
|
Attributes of those directory entries are placed into the buffer specified by
|
|
.Fa attrBuf
|
|
and
|
|
.Fa attrBufSize .
|
|
The
|
|
.Fa options
|
|
parameter allows you to modify the behaviour of the call.
|
|
.Pp
|
|
.
|
|
.Pp
|
|
.
|
|
.\" dirfd parameter
|
|
.
|
|
The
|
|
.Fa dirfd
|
|
parameter must be a file descriptor that references a directory that you have opened for reading.
|
|
.Pp
|
|
.
|
|
.\" attrList parameter
|
|
.
|
|
The
|
|
.Fa attrList
|
|
parameter is a pointer to an
|
|
.Vt attrlist
|
|
structure.
|
|
All fields of this structure must be filled before calling the function.
|
|
See the discussion of the
|
|
.Xr getattrlist 2
|
|
function for a detailed description of this structure.
|
|
To get an attribute, the corresponding bit in the appropriate
|
|
.Vt attrgroup_t
|
|
field of the
|
|
.Vt attrlist
|
|
structure must be set.
|
|
Volume attributes cannot be requested but all other supported getattrlist attributes can be used. For this function,
|
|
.Dv ATTR_CMN_NAME
|
|
and
|
|
.Dv ATTR_CMN_RETURNED_ATTRS
|
|
are required and the absence of these attributes in the attrList parameter results in an error. Note that
|
|
not all attributes supported by
|
|
.Fn getattrlist
|
|
may be vended back by this call, which is why the aforementioned flag must be supplied. In particular
|
|
.Dv ATTR_CMN_FULLPATH
|
|
may not be valid on all directory entries whose information is requested by this call.
|
|
.Pp
|
|
.
|
|
.\" attrBuf and attrBufSize parameters
|
|
.
|
|
The
|
|
.Fa attrBuf
|
|
and
|
|
.Fa attrBufSize
|
|
parameters specify a buffer into which the function places attribute values.
|
|
The attributes for any given directory entry are grouped together and
|
|
packed in exactly the same way as they are returned from
|
|
.Xr getattrlist 2
|
|
and are subject to exactly the same alignment specifications
|
|
and restrictions. These groups are then placed into the buffer, one after another.
|
|
.Xr getattrlist 2 should be consulted on details of the attributes that can be
|
|
requested for and returned. The name of the entry itself is provided by the
|
|
.Dv ATTR_CMN_NAME
|
|
attribute. Each group starts with a leading
|
|
.Vt uint32_t
|
|
, which will always be 8-byte aligned that contains the overall length of the group.
|
|
You can step from one group to the next by simply adding this length to your pointer.
|
|
The sample code (below) shows how to do this.
|
|
The initial contents of this buffer are ignored.
|
|
.Pp
|
|
.
|
|
.\" options parameter
|
|
.
|
|
The
|
|
.Fa options
|
|
parameter is a bit set that controls the behaviour of
|
|
.Fn getattrlistbulk .
|
|
The following option bits are defined.
|
|
.
|
|
.Bl -tag -width FSOPT_PACK_INVAL_ATTRS
|
|
.
|
|
.It FSOPT_PACK_INVAL_ATTRS
|
|
If this is bit is set, then all requested attributes,
|
|
even ones that are not supported by the object or file
|
|
file system, will be returned the attrBuf. The attributes
|
|
actually returned can be determined by looking at the
|
|
attribute_set_t structure returned for the
|
|
.Dv ATTR_CMN_RETURNED_ATTRS
|
|
attribute. Default values will be returned for invalid
|
|
attributes and should be ignored.
|
|
.Pp
|
|
Please see the discussion of this flag in
|
|
.Xr getattrlist 2
|
|
.
|
|
.El
|
|
.Pp
|
|
If
|
|
.Dv ATTR_CMN_ERROR
|
|
has been requested and an error specific to a directory entry occurs,
|
|
an error will be reported. The
|
|
.Dv ATTR_CMN_ERROR
|
|
attribute is a uint32_t which, if non-zero, specifies the error code
|
|
that was encountered during the processing of that directory entry. The
|
|
.Dv ATTR_CMN_ERROR
|
|
attribute will be after
|
|
.Dv ATTR_CMN_RETURNED_ATTRS
|
|
attribute in the returned buffer.
|
|
.Pp
|
|
It is typical to ask for a combination of common, file, and directory
|
|
attributes and then use the value of the
|
|
.Dv ATTR_CMN_OBJTYPE
|
|
attribute to parse the resulting attribute buffer.
|
|
.Pp
|
|
A directory which is a mount point for a file system, will have a value of
|
|
.Dq DIR_MNTSTATUS_MNTPOINT
|
|
set for its ATTR_DIR_MOUNTSTATUS attribute entry.
|
|
However the attributes for the mount point will be those from the (underlying) file system.
|
|
To get the attributes of the mounted root directory, call
|
|
.Xr getattrlist 2
|
|
on the mount point.
|
|
.Pp
|
|
A directory which is a firmlink will have the
|
|
.Dq SF_FIRMLINK
|
|
flag set in its ATTR_CMN_FLAGS attribute entry.
|
|
However, the attributes returned by
|
|
.Fn getattrlistbulk
|
|
will be those from the firmlink, not the firmlink's target.
|
|
To get the attribute of the firmlink's target, call
|
|
.Xr getattrlist 2
|
|
on the firmlink.
|
|
.
|
|
.Sh RETURN VALUES
|
|
Upon successful completion the numbers of entries successfully read
|
|
is returned. A value of 0 indicates there are no more entries. Once 0 is returned,
|
|
no further entries are returned even if new entries are added to the directory.
|
|
Directory iteration should be restarted either by repostioning the offset to 0 by
|
|
.Fn lseek
|
|
or by closing the file descriptor and opening the directory again. On error,
|
|
a value of -1 is returned and
|
|
.Va errno
|
|
is set to indicate the error.
|
|
.Pp
|
|
When iterating all entries in a directory,
|
|
.Fn getattrlistbulk
|
|
is called repeatedly until a 0 is returned. In such a case if
|
|
.Fn readdir
|
|
and
|
|
.Fn getattrlistbulk
|
|
calls on the same fd are mixed, the behavior is undefined.
|
|
|
|
.Pp
|
|
.Sh ERRORS
|
|
.Fn getattrlistbulk
|
|
will fail if:
|
|
.Bl -tag -width Er
|
|
.
|
|
.It Bq Er EBADF
|
|
.Fa dirfd
|
|
is not a valid file descriptor for a directory open for reading.
|
|
.
|
|
.It Bq Er ENOTDIR
|
|
The File descriptor
|
|
.Fa dirfd
|
|
is not a directory.
|
|
.
|
|
.It Bq Er EACCES
|
|
Search permission is denied on the directory whose descriptor is given
|
|
as input.
|
|
.
|
|
.It Bq Er EFAULT
|
|
.Fa attrList
|
|
or
|
|
.Em attrBuf
|
|
points to an invalid address.
|
|
.
|
|
.It Bq Er ERANGE
|
|
The buffer was too small.
|
|
.
|
|
.It Bq Er EINVAL
|
|
The
|
|
.Fa bitmapcount
|
|
field of
|
|
.Fa attrList
|
|
is not
|
|
.Dv ATTR_BIT_MAP_COUNT .
|
|
.
|
|
.It Bq Er EINVAL
|
|
An invalid attribute was requested.
|
|
.
|
|
.It Bq Er EINVAL
|
|
Volume attributes were requested.
|
|
.
|
|
.It Bq Er EINVAL
|
|
.Dv ATTR_CMN_NAME
|
|
or
|
|
.Dv ATTR_CMN_RETURNED_ATTRS
|
|
was not requested in the attrList parameter.
|
|
.
|
|
.It Bq Er EIO
|
|
An I/O error occurred while reading from or writing to the file system.
|
|
.El
|
|
.Pp
|
|
.
|
|
.Sh EXAMPLES
|
|
.
|
|
The following code lists the contents of a directory using
|
|
.Fn getattrlistbulk .
|
|
The listing includes the file type.
|
|
.
|
|
.Bd -literal
|
|
#include <sys/syscall.h>
|
|
#include <sys/attr.h>
|
|
#include <sys/errno.h>
|
|
#include <sys/vnode.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
#include <stddef.h>
|
|
#include <string.h>
|
|
#include <stdbool.h>
|
|
|
|
typedef struct val_attrs {
|
|
uint32_t length;
|
|
attribute_set_t returned;
|
|
uint32_t error;
|
|
attrreference_t name_info;
|
|
char *name;
|
|
fsobj_type_t obj_type;
|
|
} val_attrs_t;
|
|
|
|
|
|
void demo(const char *dirpath)
|
|
{
|
|
int error;
|
|
int dirfd;
|
|
struct attrlist attrList;
|
|
char *entry_start;
|
|
char attrBuf[256];
|
|
|
|
memset(&attrList, 0, sizeof(attrList));
|
|
attrList.bitmapcount = ATTR_BIT_MAP_COUNT;
|
|
attrList.commonattr = ATTR_CMN_RETURNED_ATTRS |
|
|
ATTR_CMN_NAME |
|
|
ATTR_CMN_ERROR |
|
|
ATTR_CMN_OBJTYPE;
|
|
|
|
error = 0;
|
|
dirfd = open(dirpath, O_RDONLY, 0);
|
|
if (dirfd < 0) {
|
|
error = errno;
|
|
printf("Could not open directory %s", dirpath);
|
|
perror("Error was ");
|
|
} else {
|
|
for (;;) {
|
|
int retcount;
|
|
|
|
retcount = getattrlistbulk(dirfd, &attrList, &attrBuf[0],
|
|
sizeof(attrBuf), 0);
|
|
printf("\engetattrlistbulk returned %d", retcount);
|
|
if (retcount == -1) {
|
|
error = errno;
|
|
perror("Error returned : ");
|
|
printf("\en");
|
|
break;
|
|
} else if (retcount == 0) {
|
|
/* No more entries in directory */
|
|
error = 0;
|
|
break;
|
|
} else {
|
|
int index;
|
|
uint32_t total_length;
|
|
char *field;
|
|
|
|
entry_start = &attrBuf[0];
|
|
total_length = 0;
|
|
printf(" -> entries returned");
|
|
for (index = 0; index < retcount; index++) {
|
|
val_attrs_t attrs = {0};
|
|
|
|
printf("\en Entry %d", index);
|
|
printf(" -- ");
|
|
field = entry_start;
|
|
attrs.length = *(uint32_t *)field;
|
|
printf(" Length %d ", attrs.length);
|
|
total_length += attrs.length;
|
|
printf(" Total Length %d ", total_length);
|
|
field += sizeof(uint32_t);
|
|
printf(" -- ");
|
|
|
|
/* set starting point for next entry */
|
|
entry_start += attrs.length;
|
|
|
|
attrs.returned = *(attribute_set_t *)field;
|
|
field += sizeof(attribute_set_t);
|
|
|
|
if (attrs.returned.commonattr & ATTR_CMN_ERROR) {
|
|
attrs.error = *(uint32_t *)field;
|
|
field += sizeof(uint32_t);
|
|
}
|
|
|
|
if (attrs.returned.commonattr & ATTR_CMN_NAME) {
|
|
attrs.name = field;
|
|
attrs.name_info = *(attrreference_t *)field;
|
|
field += sizeof(attrreference_t);
|
|
printf(" %s ", (attrs.name +
|
|
attrs.name_info.attr_dataoffset));
|
|
}
|
|
|
|
/* Check for error for this entry */
|
|
if (attrs.error) {
|
|
/*
|
|
* Print error and move on to next
|
|
* entry
|
|
*/
|
|
printf("Error in reading attributes for directory \
|
|
entry %d", attrs.error);
|
|
continue;
|
|
}
|
|
|
|
printf(" -- ");
|
|
if (attrs.returned.commonattr & ATTR_CMN_OBJTYPE) {
|
|
attrs.obj_type = *(fsobj_type_t *)field;
|
|
field += sizeof(fsobj_type_t);
|
|
|
|
switch (attrs.obj_type) {
|
|
case VREG:
|
|
printf("file ");
|
|
break;
|
|
case VDIR:
|
|
printf("directory ");
|
|
break;
|
|
default:
|
|
printf("obj_type = %-2d ", attrs.obj_type);
|
|
break;
|
|
}
|
|
}
|
|
printf(" -- ");
|
|
}
|
|
}
|
|
}
|
|
(void)close(dirfd);
|
|
}
|
|
}
|
|
.Ed
|
|
.Pp
|
|
.
|
|
.Sh SEE ALSO
|
|
.
|
|
.Xr getattrlist 2 ,
|
|
.Xr lseek 2
|
|
.
|
|
.Sh HISTORY
|
|
A
|
|
.Fn getattrlistbulk
|
|
function call appeared in OS X version 10.10
|
|
.
|