]> git.saurik.com Git - apple/xnu.git/blob - bsd/man/man2/getdirentriesattr.2
cc6c35ec70382917f525f36770030852979239ff
[apple/xnu.git] / bsd / man / man2 / getdirentriesattr.2
1 q.\" 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
39 The
40 .Fn getdirentriesattr
41 function reads directory entries and returns their attributes (that is, metadata).
42 You can think of it as a combination of
43 .Xr getdirentries 2
44 and
45 .Xr getattrlist 2 .
46 .Fn getdirentriesattr
47 iterates over the items in a directory like
48 .Xr getdirentries 2 ,
49 and returns information about each directory entry like
50 .Xr getattrlist 2 .
51 Note: when
52 .Fn getdirentriesattr
53 returns information about a symbolic link, the information returned is about the link itself, not the target of the link.
54 .Pp
55 The function reads directory entries from the directory referenced by the
56 file descriptor
57 .Fa fd .
58 Attributes of those directory entries are placed into the buffer specified by
59 .Fa attrBuf
60 and
61 .Fa attrBufSize .
62 The
63 .Fa attrList
64 parameter determines what attributes are returned for each entry.
65 The
66 .Fa count
67 parameter contains the number of directory entries requested and returned.
68 The
69 .Fa basep
70 parameter returns the directory offset in a manner similar to
71 .Xr getdirentries 2 .
72 The
73 .Fa newState
74 parameter allows you to check whether the directory has been modified while
75 you were reading it.
76 The
77 .Fa options
78 parameter lets you control specific aspects of the function's behaviour.
79 .Pp
80 .
81 The
82 .Fn getdirentriesattr
83 function is only supported by certain volume format implementations.
84 For maximum compatibility, client programs should use high-level APIs
85 (such as the Carbon File Manager) to access file system attributes.
86 These high-level APIs include logic to emulate file system attributes
87 on volumes that don't support
88 .Fn getdirentriesattr .
89 .Pp
90 .
91 .\" fd parameter
92 .
93 The
94 .Fa fd
95 parameter must be a file descriptor that references a directory that you have opened for reading.
96 .Pp
97 .
98 .\" attrList parameter
99 .
100 The
101 .Fa attrList
102 parameter is a pointer to an
103 .Vt attrlist
104 structure.
105 You are responsible for filling out all fields of this structure before calling the function.
106 See the discussion of the
107 .Xr getattrlist 2
108 function for a detailed description of this structure.
109 To get an attribute you must set the corresponding bit in the appropriate
110 .Vt attrgroup_t
111 field of the
112 .Vt attrlist
113 structure.
114 You must not request volume attributes.
115 .Pp
116 .
117 .\" attrBuf and attrBufSize parameters
118 .
119 The
120 .Fa attrBuf
121 and
122 .Fa attrBufSize
123 parameters specify a buffer into which the function places attribute values.
124 The attributes for any given directory entry are grouped together and
125 packed in exactly the same way as they are returned from
126 .Xr getattrlist 2 .
127 These groups are then placed into the buffer, one after another.
128 As each group starts with a leading
129 .Vt u_int32_t
130 that contains the
131 overall length of the group, you can step from one group to the next
132 by simply adding this length to your pointer.
133 The sample code (below) shows how to do this.
134 The initial contents of this buffer are ignored.
135 .Pp
136 .
137 .\" count parameter
138 .
139 The
140 .Fa count
141 parameter points to an
142 .Vt unsigned long
143 or
144 .Vt unsigned int
145 variable.
146 You should initialise this variable to be the number of directory entries for which
147 you wish to get attributes.
148 On return, this variable contains the number of directory entries whose attributes
149 have been placed into the attribute buffer.
150 This may be smaller than the number that you requested.
151 .Pp
152 .
153 .\" basep parameter
154 The
155 .Fa basep
156 parameter returns the offset of the last directory entry read, in a
157 manner identical to
158 .Xr getdirentries 2 .
159 You can use this value to reset a directory iteration to a known position
160 using
161 .Xr lseek 2 .
162 However, since the variable is too small to hold an
163 .Vt off_t ,
164 you should use
165 .Xr lseek 2
166 to get the directory's current position instead of using this parameter.
167 The initial value of the variable is ignored.
168 .Pp
169 .
170 .\" newState parameter
171 .
172 The
173 .Fa newState
174 parameter returns a value that changes if the directory has been modified.
175 If you're iterating through the directory by making repeated calls to
176 .Fn getdirentriesattr ,
177 you can compare subsequent values of
178 .Fa newState
179 to determine whether the directory has been modified (and thus restart
180 your iteration at the beginning).
181 The initial value of the variable is ignored.
182 .Pp
183 .
184 .\" options parameter
185 .
186 The
187 .Fa options
188 parameter is a bit set that controls the behaviour of
189 .Fn getdirentriesattr .
190 The following option bits are defined.
191 .
192 .Bl -tag -width FSOPT_NOINMEMUPDATE
193 .
194 .It FSOPT_NOINMEMUPDATE
195 This tells
196 .Fn getdirentriesattr
197 to return the directory entries from disk rather than taking the extra step of looking
198 at data structures in-memory which may contain changes that haven't been flushed to disk.
199 .Pp
200 This option allowed for specific performance optimizations for specific clients on older systems.
201 We currently recommend that clients not set this option and that file system
202 implementations ignore it.
203 .
204 .El
205 .Pp
206 It is typical to ask for a combination of common, file, and directory
207 attributes and then use the value of the
208 .Dv ATTR_CMN_OBJTYPE
209 attribute to parse the resulting attribute buffer.
210 .Sh NOTES
211 As of Mac OS X 10.10,
212 .Fn getdirentriesattr
213 is deprecated. It is replaced by
214 .Nm getattrlistbulk(2).
215 Continued use of
216 .Fn getdirentriesattr
217 is strongly discouraged as comprehensive results are not guaranteed.
218 .Sh RETURN VALUES
219 Upon successful completion a value of 0 or 1 is returned.
220 The value 0 indicates that the routine completed successfully.
221 The value 1 indicates that the routine completed successfully and has
222 returned the last entry in the directory.
223 On error, a value of -1 is returned and
224 .Va errno
225 is set to indicate the error.
226 .
227 .Sh COMPATIBILITY
228 Not all volumes support
229 .Fn getdirentriesattr .
230 You can test whether a volume supports
231 .Fn getdirentriesattr
232 by using
233 .Xr getattrlist 2
234 to get the volume capabilities attribute
235 .Dv ATTR_VOL_CAPABILITIES ,
236 and then testing the
237 .Dv VOL_CAP_INT_READDIRATTR
238 flag.
239 .Pp
240 .
241 The
242 .Fn getdirentriesattr
243 function has been undocumented for more than two years.
244 In that time a number of volume format implementations have been created without
245 a proper specification for the behaviour of this routine.
246 You may encounter volume format implementations with slightly different
247 behaviour than what is described here.
248 Your program is expected to be tolerant of this variant behaviour.
249 .Pp
250 .
251 If you're implementing a volume format that supports
252 .Fn getdirentriesattr ,
253 you should be careful to support the behaviour specified by this document.
254 .
255 .Pp
256 If the directory contains a mount point, then
257 .Dq DIR_MNTSTATUS_MNTPOINT
258 will be set in the
259 .Dv ATTR_DIR_MOUNTSTATUS
260 for that entry; all other attributes for that entry, however,
261 will be for the underlying file system (as opposed to the mounted
262 file system).
263 .Xr getattrlist 2
264 should be used to get the attributes for the mount point.
265 .Pp
266 A directory which is a firmlink will have the
267 .Dq SF_FIRMLINK
268 flag set in its
269 ATTR_CMN_FLAGS attribute entry.
270 However the attributes returned by
271 .Fn getdirentriesattr
272 will be those from the firmlink, not the firmlink's target.
273 To get the attributes of the firmlink's target, call
274 .Xr getattrlist 2
275 on the firmlink.
276 .Sh ERRORS
277 .Fn getdirentriesattr
278 will fail if:
279 .Bl -tag -width Er
280 .
281 .It Bq Er ENOTSUP
282 The volume does not support
283 .Fn getdirentriesattr .
284 .
285 .It Bq Er EBADF
286 .Fa fd
287 is not a valid file descriptor for a directory open for reading.
288 .
289 .It Bq Er EFAULT
290 .Fa attrList
291 or
292 .Em attrBuf
293 points to an invalid address.
294 .
295 .It Bq Er EINVAL
296 The
297 .Fa bitmapcount
298 field of
299 .Fa attrList
300 is not
301 .Dv ATTR_BIT_MAP_COUNT .
302 .
303 .It Bq Er EINVAL
304 You requested an invalid attribute.
305 .
306 .It Bq Er EINVAL
307 You requested volume attributes.
308 .
309 .It Bq Er EINVAL
310 The
311 .Fa options
312 parameter contains an invalid flag.
313 .
314 .It Bq Er EIO
315 An I/O error occurred while reading from or writing to the file system.
316 .El
317 .Pp
318 .
319 .Sh EXAMPLES
320 .
321 The following code lists the contents of a directory using
322 .Fn getdirentriesattr .
323 The 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 .
338 typedef struct attrlist attrlist_t;
339 .Pp
340 .
341 struct 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));
348 typedef struct FInfoAttrBuf FInfoAttrBuf;
349 .Pp
350 .
351 enum {
352 kEntriesPerCall = 10
353 };
354 .Pp
355 .
356 static 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
487 A
488 .Fn getdirentriesattr
489 function call appeared in Darwin 1.3.1 (Mac OS X version 10.0).
490 .