1q.\" Copyright (c) 2003 Apple Computer, Inc. All rights reserved. 2.\" 3.\" The contents of this file constitute Original Code as defined in and 4.\" are subject to the Apple Public Source License Version 1.1 (the 5.\" "License"). You may not use this file except in compliance with the 6.\" License. Please obtain a copy of the License at 7.\" http://www.apple.com/publicsource and read it before using this file. 8.\" 9.\" This Original Code and all software distributed under the License are 10.\" distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 11.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 12.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 13.\" FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 14.\" License for the specific language governing rights and limitations 15.\" under the License. 16.\" 17.\" @(#)getdirentriesattr.2 18. 19.Dd December 15, 2003 20.Dt GETDIRENTRIESATTR 2 21.Os Darwin 22.Sh NAME 23.Nm getdirentriesattr(NOW DEPRECATED) 24.Nd get file system attributes for multiple directory entries 25.Sh SYNOPSIS 26.Fd #include <sys/attr.h> 27.Fd #include <unistd.h> 28.Pp 29.Fd #if __LP64__ 30.Ft int 31.Fn getdirentriesattr "int fd" "struct attrlist * attrList" "void * attrBuf" "size_t attrBufSize" "unsigned int * count" "unsigned int * basep" "unsigned int * newState" "unsigned int options" 32.Fd #else 33.Ft int 34.Fn getdirentriesattr "int fd" "struct attrlist * attrList" "void * attrBuf" "size_t attrBufSize" "unsigned long * count" "unsigned long * basep" "unsigned long * newState" "unsigned long options" 35.Fd #endif 36. 37. 38.Sh DESCRIPTION 39The 40.Fn getdirentriesattr 41function reads directory entries and returns their attributes (that is, metadata). 42You can think of it as a combination of 43.Xr getdirentries 2 44and 45.Xr getattrlist 2 . 46.Fn getdirentriesattr 47iterates over the items in a directory like 48.Xr getdirentries 2 , 49and returns information about each directory entry like 50.Xr getattrlist 2 . 51Note: when 52.Fn getdirentriesattr 53returns information about a symbolic link, the information returned is about the link itself, not the target of the link. 54.Pp 55The function reads directory entries from the directory referenced by the 56file descriptor 57.Fa fd . 58Attributes of those directory entries are placed into the buffer specified by 59.Fa attrBuf 60and 61.Fa attrBufSize . 62The 63.Fa attrList 64parameter determines what attributes are returned for each entry. 65The 66.Fa count 67parameter contains the number of directory entries requested and returned. 68The 69.Fa basep 70parameter returns the directory offset in a manner similar to 71.Xr getdirentries 2 . 72The 73.Fa newState 74parameter allows you to check whether the directory has been modified while 75you were reading it. 76The 77.Fa options 78parameter lets you control specific aspects of the function's behaviour. 79.Pp 80. 81The 82.Fn getdirentriesattr 83function is only supported by certain volume format implementations. 84For maximum compatibility, client programs should use high-level APIs 85(such as the Carbon File Manager) to access file system attributes. 86These high-level APIs include logic to emulate file system attributes 87on volumes that don't support 88.Fn getdirentriesattr . 89.Pp 90. 91.\" fd parameter 92. 93The 94.Fa fd 95parameter must be a file descriptor that references a directory that you have opened for reading. 96.Pp 97. 98.\" attrList parameter 99. 100The 101.Fa attrList 102parameter is a pointer to an 103.Vt attrlist 104structure. 105You are responsible for filling out all fields of this structure before calling the function. 106See the discussion of the 107.Xr getattrlist 2 108function for a detailed description of this structure. 109To get an attribute you must set the corresponding bit in the appropriate 110.Vt attrgroup_t 111field of the 112.Vt attrlist 113structure. 114You must not request volume attributes. 115.Pp 116. 117.\" attrBuf and attrBufSize parameters 118. 119The 120.Fa attrBuf 121and 122.Fa attrBufSize 123parameters specify a buffer into which the function places attribute values. 124The attributes for any given directory entry are grouped together and 125packed in exactly the same way as they are returned from 126.Xr getattrlist 2 . 127These groups are then placed into the buffer, one after another. 128As each group starts with a leading 129.Vt u_int32_t 130that contains the 131overall length of the group, you can step from one group to the next 132by simply adding this length to your pointer. 133The sample code (below) shows how to do this. 134The initial contents of this buffer are ignored. 135.Pp 136. 137.\" count parameter 138. 139The 140.Fa count 141parameter points to an 142.Vt unsigned long 143or 144.Vt unsigned int 145variable. 146You should initialise this variable to be the number of directory entries for which 147you wish to get attributes. 148On return, this variable contains the number of directory entries whose attributes 149have been placed into the attribute buffer. 150This may be smaller than the number that you requested. 151.Pp 152. 153.\" basep parameter 154The 155.Fa basep 156parameter returns the offset of the last directory entry read, in a 157manner identical to 158.Xr getdirentries 2 . 159You can use this value to reset a directory iteration to a known position 160using 161.Xr lseek 2 . 162However, since the variable is too small to hold an 163.Vt off_t , 164you should use 165.Xr lseek 2 166to get the directory's current position instead of using this parameter. 167The initial value of the variable is ignored. 168.Pp 169. 170.\" newState parameter 171. 172The 173.Fa newState 174parameter returns a value that changes if the directory has been modified. 175If you're iterating through the directory by making repeated calls to 176.Fn getdirentriesattr , 177you can compare subsequent values of 178.Fa newState 179to determine whether the directory has been modified (and thus restart 180your iteration at the beginning). 181The initial value of the variable is ignored. 182.Pp 183. 184.\" options parameter 185. 186The 187.Fa options 188parameter is a bit set that controls the behaviour of 189.Fn getdirentriesattr . 190The following option bits are defined. 191. 192.Bl -tag -width FSOPT_NOINMEMUPDATE 193. 194.It FSOPT_NOINMEMUPDATE 195This tells 196.Fn getdirentriesattr 197to return the directory entries from disk rather than taking the extra step of looking 198at data structures in-memory which may contain changes that haven't been flushed to disk. 199.Pp 200This option allowed for specific performance optimizations for specific clients on older systems. 201We currently recommend that clients not set this option and that file system 202implementations ignore it. 203. 204.El 205.Pp 206It is typical to ask for a combination of common, file, and directory 207attributes and then use the value of the 208.Dv ATTR_CMN_OBJTYPE 209attribute to parse the resulting attribute buffer. 210.Sh NOTES 211As of Mac OS X 10.10, 212.Fn getdirentriesattr 213is deprecated. It is replaced by 214.Nm getattrlistbulk(2). 215Continued use of 216.Fn getdirentriesattr 217is strongly discouraged as comprehensive results are not guaranteed. 218.Sh RETURN VALUES 219Upon successful completion a value of 0 or 1 is returned. 220The value 0 indicates that the routine completed successfully. 221The value 1 indicates that the routine completed successfully and has 222returned the last entry in the directory. 223On error, a value of -1 is returned and 224.Va errno 225is set to indicate the error. 226. 227.Sh COMPATIBILITY 228Not all volumes support 229.Fn getdirentriesattr . 230You can test whether a volume supports 231.Fn getdirentriesattr 232by using 233.Xr getattrlist 2 234to get the volume capabilities attribute 235.Dv ATTR_VOL_CAPABILITIES , 236and then testing the 237.Dv VOL_CAP_INT_READDIRATTR 238flag. 239.Pp 240. 241The 242.Fn getdirentriesattr 243function has been undocumented for more than two years. 244In that time a number of volume format implementations have been created without 245a proper specification for the behaviour of this routine. 246You may encounter volume format implementations with slightly different 247behaviour than what is described here. 248Your program is expected to be tolerant of this variant behaviour. 249.Pp 250. 251If you're implementing a volume format that supports 252.Fn getdirentriesattr , 253you should be careful to support the behaviour specified by this document. 254. 255.Pp 256If the directory contains a mount point, then 257.Dq DIR_MNTSTATUS_MNTPOINT 258will be set in the 259.Dv ATTR_DIR_MOUNTSTATUS 260for that entry; all other attributes for that entry, however, 261will be for the underlying file system (as opposed to the mounted 262file system). 263.Xr getattrlist 2 264should be used to get the attributes for the mount point. 265.Pp 266A directory which is a firmlink will have the 267.Dq SF_FIRMLINK 268flag set in its 269ATTR_CMN_FLAGS attribute entry. 270However the attributes returned by 271.Fn getdirentriesattr 272will be those from the firmlink, not the firmlink's target. 273To get the attributes of the firmlink's target, call 274.Xr getattrlist 2 275on the firmlink. 276.Sh ERRORS 277.Fn getdirentriesattr 278will fail if: 279.Bl -tag -width Er 280. 281.It Bq Er ENOTSUP 282The volume does not support 283.Fn getdirentriesattr . 284. 285.It Bq Er EBADF 286.Fa fd 287is not a valid file descriptor for a directory open for reading. 288. 289.It Bq Er EFAULT 290.Fa attrList 291or 292.Em attrBuf 293points to an invalid address. 294. 295.It Bq Er EINVAL 296The 297.Fa bitmapcount 298field of 299.Fa attrList 300is not 301.Dv ATTR_BIT_MAP_COUNT . 302. 303.It Bq Er EINVAL 304You requested an invalid attribute. 305. 306.It Bq Er EINVAL 307You requested volume attributes. 308. 309.It Bq Er EINVAL 310The 311.Fa options 312parameter contains an invalid flag. 313. 314.It Bq Er EIO 315An I/O error occurred while reading from or writing to the file system. 316.El 317.Pp 318. 319.Sh EXAMPLES 320. 321The following code lists the contents of a directory using 322.Fn getdirentriesattr . 323The listing includes the file type and creator for files. 324. 325.Bd -literal 326#include <assert.h> 327#include <stdio.h> 328#include <stddef.h> 329#include <string.h> 330#include <sys/attr.h> 331#include <sys/errno.h> 332#include <unistd.h> 333#include <sys/vnode.h> 334#include <stdbool.h> 335#include <fcntl.h> 336.Pp 337. 338typedef struct attrlist attrlist_t; 339.Pp 340. 341struct FInfoAttrBuf { 342 u_int32_t length; 343 attrreference_t name; 344 fsobj_type_t objType; 345 char finderInfo[32]; 346 u_int32_t dirStatus; 347} __attribute__((aligned(4), packed)); 348typedef struct FInfoAttrBuf FInfoAttrBuf; 349.Pp 350. 351enum { 352 kEntriesPerCall = 10 353}; 354.Pp 355. 356static int FInfoDemo(const char *dirPath) 357{ 358 int err; 359 int junk; 360 int dirFD; 361 attrlist_t attrList; 362#ifdef __LP64__ 363 unsigned int index; 364 unsigned int count; 365 unsigned int junkBaseP; 366 unsigned int oldState; 367 unsigned int newState; 368#else 369 unsigned long index; 370 unsigned long count; 371 unsigned long junkBaseP; 372 unsigned long oldState; 373 unsigned long newState; 374#endif 375 bool oldStateValid; 376 bool done; 377 FInfoAttrBuf * thisEntry; 378 char attrBuf[kEntriesPerCall * (sizeof(FInfoAttrBuf) + 64)]; 379.Pp 380. 381 // attrBuf is big enough for kEntriesPerCall entries, assuming that 382 // the average name length is less than 64. 383.Pp 384. 385 memset(&attrList, 0, sizeof(attrList)); 386 attrList.bitmapcount = ATTR_BIT_MAP_COUNT; 387 attrList.commonattr = ATTR_CMN_NAME 388 | ATTR_CMN_OBJTYPE 389 | ATTR_CMN_FNDRINFO; 390 attrList.dirattr = ATTR_DIR_MOUNTSTATUS; 391.Pp 392 393 err = 0; 394 dirFD = open(dirPath, O_RDONLY, 0); 395 if (dirFD < 0) { 396 err = errno; 397 } 398 if (err == 0) { 399 oldStateValid = false; 400 done = false; 401 do { 402 count = kEntriesPerCall; 403.Pp 404 err = getdirentriesattr( 405 dirFD, 406 &attrList, 407 &attrBuf, 408 sizeof(attrBuf), 409 &count, 410 &junkBaseP, 411 &newState, 412 0 413 ); 414 if (err < 0) { 415 err = errno; 416 } else { 417 done = err; 418 err = 0; 419 } 420.Pp 421 if (err == 0) { 422 if (oldStateValid) { 423 if (newState != oldState) { 424 printf("*** Directory has changed\en"); 425 oldState = newState; 426 } 427 } else { 428 oldState = newState; 429 oldStateValid = true; 430 } 431.Pp 432 thisEntry = (FInfoAttrBuf *) attrBuf; 433.Pp 434 for (index = 0; index < count; index++) { 435 switch (thisEntry->objType) { 436 case VREG: 437 printf( 438 "'%4.4s' '%4.4s' ", 439 &thisEntry->finderInfo[0], 440 &thisEntry->finderInfo[4] 441 ); 442 break; 443 case VDIR: 444 if (thisEntry->dirStatus & DIR_MNTSTATUS_MNTPOINT) 445 printf("mount-point "); 446 else 447 printf("directory "); 448 break; 449 default: 450 printf( 451 "objType = %-2d ", 452 thisEntry->objType 453 ); 454 break; 455 } 456 printf( 457 "%s\en", 458 ((char *) &thisEntry->name) 459 + thisEntry->name.attr_dataoffset 460 ); 461.Pp 462 // Advance to the next entry. 463.Pp 464 thisEntry = (FInfoAttrBuf*)((char*)thisEntry + thisEntry->length); 465 } 466 } 467 } while ( err == 0 && ! done ); 468 } 469.Pp 470 if (dirFD != -1) { 471 junk = close(dirFD); 472 assert(junk == 0); 473 } 474.Pp 475 return err; 476} 477.Ed 478.Pp 479. 480.Sh SEE ALSO 481. 482.Xr getattrlist 2 , 483.Xr getdirentries 2 , 484.Xr lseek 2 485. 486.Sh HISTORY 487A 488.Fn getdirentriesattr 489function call appeared in Darwin 1.3.1 (Mac OS X version 10.0). 490. 491