Commit | Line | Data |
---|---|---|
fe8ab488 | 1 | q.\" Copyright (c) 2003 Apple Computer, Inc. All rights reserved. |
91447636 A |
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 | |
fe8ab488 | 23 | .Nm getdirentriesattr(NOW DEPRECATED) |
91447636 A |
24 | .Nd get file system attributes for multiple directory entries |
25 | .Sh SYNOPSIS | |
26 | .Fd #include <sys/attr.h> | |
27 | .Fd #include <unistd.h> | |
b0d623f7 A |
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 | |
91447636 A |
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" | |
b0d623f7 | 35 | .Fd #endif |
91447636 A |
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 . | |
b0d623f7 A |
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 | |
91447636 A |
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 | |
b0d623f7 | 129 | .Vt u_int32_t |
91447636 A |
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 | |
b0d623f7 A |
141 | parameter points to an |
142 | .Vt unsigned long | |
143 | or | |
144 | .Vt unsigned int | |
91447636 A |
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 . | |
b0d623f7 A |
162 | However, since the variable is too small to hold an |
163 | .Vt off_t , | |
164 | you should use | |
165 | .Xr lseek 2 | |
6d2010ae | 166 | to get the directory's current position instead of using this parameter. |
91447636 A |
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. | |
fe8ab488 A |
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. | |
91447636 A |
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 | . | |
6d2010ae A |
255 | .Pp |
256 | If the directory contains a mount point, then | |
cb323159 | 257 | .Dq DIR_MNTSTATUS_MNTPOINT |
6d2010ae A |
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. | |
cb323159 A |
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. | |
91447636 A |
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 { | |
b0d623f7 | 342 | u_int32_t length; |
91447636 A |
343 | attrreference_t name; |
344 | fsobj_type_t objType; | |
345 | char finderInfo[32]; | |
6d2010ae A |
346 | u_int32_t dirStatus; |
347 | } __attribute__((aligned(4), packed)); | |
91447636 A |
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; | |
b0d623f7 A |
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 | |
91447636 A |
369 | unsigned long index; |
370 | unsigned long count; | |
371 | unsigned long junkBaseP; | |
91447636 A |
372 | unsigned long oldState; |
373 | unsigned long newState; | |
b0d623f7 A |
374 | #endif |
375 | bool oldStateValid; | |
91447636 A |
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; | |
6d2010ae | 390 | attrList.dirattr = ATTR_DIR_MOUNTSTATUS; |
91447636 A |
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: | |
6d2010ae A |
444 | if (thisEntry->dirStatus & DIR_MNTSTATUS_MNTPOINT) |
445 | printf("mount-point "); | |
446 | else | |
447 | printf("directory "); | |
91447636 A |
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 | |
6d2010ae | 464 | thisEntry = (FInfoAttrBuf*)((char*)thisEntry + thisEntry->length); |
91447636 A |
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 | . |