Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
GETATTRLISTBULK(2)	       System Calls Manual	      GETATTRLISTBULK(2)

NAME
     getattrlistbulk  --  get  file system attributes for multiple directory en-
     tries

SYNOPSIS
     #include <sys/attr.h>
     #include <unistd.h>

     int
     getattrlistbulk(int dirfd, struct attrlist * attrList, void * attrBuf,
	 size_t attrBufSize, uint64_t options);

DESCRIPTION
     The getattrlistbulk() function iterates over the items in a  directory  and
     returns  information about each directory entry like getattrlist(2).  Note:
     when getattrlistbulk() returns information about a symbolic link,	the  in-
     formation	returned  is  about the link itself, not the target of the link.
     The order of the directory entries (and their associated  metadata)  vended
     by  getattrlistbulk()  is	not specified.	Some file systems may return en-
     tries in lexicographic sort order and others may not.

     The function reads directory entries from the directory referenced  by  the
     file  descriptor  dirfd.  The attrList parameter determines what attributes
     are returned for each entry.  Attributes of  those  directory  entries  are
     placed  into  the buffer specified by attrBuf and attrBufSize.  The options
     parameter allows you to modify the behaviour of the call.

     The dirfd parameter must be a file descriptor that references  a  directory
     that you have opened for reading.

     The  attrList  parameter is a pointer to an attrlist structure.  All fields
     of this structure must be filled before calling the function.  See the dis-
     cussion of the getattrlist(2) function for a detailed description	of  this
     structure.   To  get an attribute, the corresponding bit in the appropriate
     attrgroup_t field of the attrlist structure must be set.  Volume attributes
     cannot be requested but all other supported getattrlist attributes  can  be
     used.  For this function, ATTR_CMN_NAME and ATTR_CMN_RETURNED_ATTRS are re-
     quired and the absence of these attributes in the	attrList  parameter  re-
     sults  in an error. Note that not all attributes supported by getattrlist()
     may be vended back by this call, which is why the aforementioned flag  must
     be supplied. In particular ATTR_CMN_FULLPATH may not be valid on all direc-
     tory entries whose information is requested by this call.

     The  attrBuf  and	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 getattrlist(2) and are subject to exactly the same  alignment
     specifications  and  restrictions.  These	groups	are then placed into the
     buffer, one after another.  getattrlist(2)should be consulted on details of
     the attributes that can be requested for and returned. The name of the  en-
     try  itself  is provided by the ATTR_CMN_NAME attribute.  Each group starts
     with a leading 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.

     The options parameter is a bit set that controls the  behaviour  of  getat-
     trlistbulk().  The following option bits are defined.

     FSOPT_PACK_INVAL_ATTRS  If  this is bit is set, then all requested  attrib-
			     utes, even ones that are not supported by	the  ob-
			     ject  or file file system, will be returned the at-
			     trBuf. The attributes actually returned can be  de-
			     termined  by  looking at the attribute_set_t struc-
			     ture returned for the  ATTR_CMN_RETURNED_ATTRS  at-
			     tribute.  Default	values	will be returned for in-
			     valid attributes and should be ignored.

			     Please see the discussion of this	flag  in  getat-
			     trlist(2)

     If  ATTR_CMN_ERROR  has been requested and an error specific to a directory
     entry occurs, an error will be reported. The 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 ATTR_CMN_ERROR attribute
     will be after ATTR_CMN_RETURNED_ATTRS attribute in the returned buffer.

     It is typical to ask for a combination of common, file, and  directory  at-
     tributes  and then use the value of the ATTR_CMN_OBJTYPE attribute to parse
     the resulting attribute buffer.

     A directory which is a mount point for a file system, will have a value  of
     "DIR_MNTSTATUS_MNTPOINT"  set for its ATTR_DIR_MOUNTSTATUS attribute entry.
     However the attributes for the mount point will be those from the (underly-
     ing) file system.	To get the attributes of  the  mounted	root  directory,
     call getattrlist(2) on the mount point.

     A directory which is a firmlink will have the "SF_FIRMLINK" flag set in its
     ATTR_CMN_FLAGS attribute entry.  However, the attributes returned by getat-
     trlistbulk()  will  be  those from the firmlink, not the firmlink's target.
     To get the attribute of the firmlink's target, call getattrlist(2)  on  the
     firmlink.

RETURN VALUES
     Upon  successful completion the numbers of entries successfully read is re-
     turned. A value of 0 indicates there are no more entries.	Once  0  is  re-
     turned,  no  further  entries are returned even if new entries are added to
     the directory.  Directory iteration should be restarted  either  by  repos-
     tioning  the  offset  to 0 by lseek() or by closing the file descriptor and
     opening the directory again. On error, a value of -1 is returned and  errno
     is set to indicate the error.

     When  iterating all entries in a directory, getattrlistbulk() is called re-
     peatedly until a 0 is returned. In such a	case  if  readdir()  and  getat-
     trlistbulk() calls on the same fd are mixed, the behavior is undefined.

ERRORS
     getattrlistbulk() will fail if:

     [EBADF]		dirfd  is  not	a  valid file descriptor for a directory
			open for reading.

     [ENOTDIR]		The File descriptor dirfd is not a directory.

     [EACCES]		Search permission is denied on the directory  whose  de-
			scriptor is given as input.

     [EFAULT]		attrList or attrBuf points to an invalid address.

     [ERANGE]		The buffer was too small.

     [EINVAL]		The    bitmapcount    field    of    attrList	is   not
			ATTR_BIT_MAP_COUNT.

     [EINVAL]		An invalid attribute was requested.

     [EINVAL]		Volume attributes were requested.

     [EINVAL]		ATTR_CMN_NAME or  ATTR_CMN_RETURNED_ATTRS  was	not  re-
			quested in the attrList parameter.

     [EIO]		An  I/O  error occurred while reading from or writing to
			the file system.

EXAMPLES
     The following code lists the contents of  a  directory  using  getattrlist-
     bulk().  The listing includes the file type.

     #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("\ngetattrlistbulk returned %d", retcount);
		 if (retcount == -1) {
		     error = errno;
		     perror("Error returned : ");
		     printf("\n");
		     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("\n 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);
	 }
     }

SEE ALSO
     getattrlist(2), lseek(2)

HISTORY
     A getattrlistbulk() function call appeared in OS X version 10.10

Darwin				November 15, 2013	      GETATTRLISTBULK(2)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=getattrlistbulk&sektion=2&manpath=macOS+13.6.5>

home | help