1 /**
2 * D header file for POSIX.
3 *
4 * Copyright: Copyright Sean Kelly 2005 - 2009.
5 * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 * Authors: Sean Kelly,
7 Alex Rønne Petersn
8 * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
9 */
10
11 /* Copyright Sean Kelly 2005 - 2009.
12 * Distributed under the Boost Software License, Version 1.0.
13 * (See accompanying file LICENSE or copy at
14 * http://www.boost.org/LICENSE_1_0.txt)
15 */
16 module core.sys.posix.dirent;
17
18 import core.sys.posix.config;
19 public import core.sys.posix.sys.types; // for ino_t
20
21 version (OSX)
22 version = Darwin;
23 else version (iOS)
24 version = Darwin;
25 else version (TVOS)
26 version = Darwin;
27 else version (WatchOS)
28 version = Darwin;
29
version(Posix)30 version (Posix):
31 extern (C):
32 nothrow:
33 @nogc:
34 @system:
35
36 //
37 // Required
38 //
39 /*
40 struct dirent
41 {
42 char[] d_name;
43 }
44 */
45
46 version (linux)
47 {
48 struct dirent
49 {
50 ino_t d_ino;
51 off_t d_off;
52 ushort d_reclen;
53 ubyte d_type;
54 char[256] d_name = 0;
55 }
56 }
57 else version (Darwin)
58 {
59 // _DARWIN_FEATURE_64_BIT_INODE dirent is default for Mac OSX >10.5 and is
60 // only meaningful type for other OS X/Darwin variants (e.g. iOS).
61 // man dir(5) has some info, man stat(2) gives details.
62 struct dirent
63 {
64 ino_t d_ino;
65 alias d_fileno = d_ino;
66 ulong d_seekoff;
67 ushort d_reclen;
68 ushort d_namlen;
69 ubyte d_type;
70 char[1024] d_name = 0;
71 }
72 }
73 else version (FreeBSD)
74 {
75 import core.sys.freebsd.config;
76
77 static if (__FreeBSD_version >= 1200000)
78 {
79 struct dirent
80 {
81 ino_t d_fileno;
82 off_t d_off;
83 ushort d_reclen;
84 ubyte d_type;
85 ubyte d_pad0;
86 ushort d_namlen;
87 ushort d_pad1;
88 char[256] d_name = 0;
89 }
90 }
91 else
92 {
93 align(4)
94 struct dirent
95 {
96 uint d_fileno;
97 ushort d_reclen;
98 ubyte d_type;
99 ubyte d_namlen;
100 char[256] d_name = 0;
101 }
102 }
103 }
104 else version (NetBSD)
105 {
106 struct dirent
107 {
108 ulong d_fileno;
109 ushort d_reclen;
110 ushort d_namlen;
111 ubyte d_type;
112 char[512] d_name = 0;
113 }
114 }
115 else version (OpenBSD)
116 {
117 align(4)
118 struct dirent
119 {
120 ino_t d_fileno;
121 off_t d_off;
122 ushort d_reclen;
123 ubyte d_type;
124 ubyte d_namlen;
125 ubyte[4] __d_padding;
126 char[256] d_name = 0;
127 }
128 }
129 else version (DragonFlyBSD)
130 {
131 struct dirent
132 {
133 ino_t d_fileno; /* file number of entry */
134 ushort d_reclen; /* strlen(d_name) */
135 ubyte d_type; /* file type, see blow */
136 ubyte d_unused1; /* padding, reserved */
137 uint d_unused2; /* reserved */
138 char[256] d_name = 0; /* name, NUL-terminated */
139 }
140 }
141 else version (Solaris)
142 {
143 struct dirent
144 {
145 ino_t d_ino;
146 off_t d_off;
147 ushort d_reclen;
148 char[1] d_name = 0;
149 }
150 }
151 else
152 {
153 static assert(false, "Unsupported platform");
154 }
155
156 /*
157 DIR
158
159 int closedir(DIR*);
160 DIR* opendir(const scope char*);
161 dirent* readdir(DIR*);
162 void rewinddir(DIR*);
163 */
164
165 version (CRuntime_Glibc)
166 {
167 // NOTE: The following constants are non-standard Linux definitions
168 // for dirent.d_type.
169 enum
170 {
171 DT_UNKNOWN = 0,
172 DT_FIFO = 1,
173 DT_CHR = 2,
174 DT_DIR = 4,
175 DT_BLK = 6,
176 DT_REG = 8,
177 DT_LNK = 10,
178 DT_SOCK = 12,
179 DT_WHT = 14
180 }
181
182 struct DIR
183 {
184 // Managed by OS
185 }
186
187 static if ( __USE_FILE_OFFSET64 )
188 {
189 dirent* readdir64(DIR*);
190 alias readdir64 readdir;
191 }
192 else
193 {
194 dirent* readdir(DIR*);
195 }
196 }
197 else version (Darwin)
198 {
199 enum
200 {
201 DT_UNKNOWN = 0,
202 DT_FIFO = 1,
203 DT_CHR = 2,
204 DT_DIR = 4,
205 DT_BLK = 6,
206 DT_REG = 8,
207 DT_LNK = 10,
208 DT_SOCK = 12,
209 DT_WHT = 14
210 }
211
212 struct DIR
213 {
214 // Managed by OS
215 }
216
217 // OS X maintains backwards compatibility with older binaries using 32-bit
218 // inode functions by appending $INODE64 to newer 64-bit inode functions.
219 // Other Darwin variants (iOS, TVOS, WatchOS) only support 64-bit inodes,
220 // no suffix needed
221 version (OSX)
222 {
223 version (AArch64)
224 dirent* readdir(DIR*);
225 else
226 pragma(mangle, "readdir$INODE64") dirent* readdir(DIR*);
227 }
228 else
229 dirent* readdir(DIR*);
230 }
231 else version (FreeBSD)
232 {
233 import core.sys.freebsd.config;
234
235 // https://github.com/freebsd/freebsd/blob/master/sys/sys/dirent.h
236 enum
237 {
238 DT_UNKNOWN = 0,
239 DT_FIFO = 1,
240 DT_CHR = 2,
241 DT_DIR = 4,
242 DT_BLK = 6,
243 DT_REG = 8,
244 DT_LNK = 10,
245 DT_SOCK = 12,
246 DT_WHT = 14
247 }
248
249 alias void* DIR;
250
251 version (GNU)
252 {
253 dirent* readdir(DIR*);
254 }
255 else
256 {
257 static if (__FreeBSD_version >= 1200000)
258 pragma(mangle, "readdir@FBSD_1.5") dirent* readdir(DIR*);
259 else
260 pragma(mangle, "readdir@FBSD_1.0") dirent* readdir(DIR*);
261 }
262 }
263 else version (NetBSD)
264 {
265 enum
266 {
267 DT_UNKNOWN = 0,
268 DT_FIFO = 1,
269 DT_CHR = 2,
270 DT_DIR = 4,
271 DT_BLK = 6,
272 DT_REG = 8,
273 DT_LNK = 10,
274 DT_SOCK = 12,
275 DT_WHT = 14
276 }
277
278 alias void* DIR;
279
280 dirent* __readdir30(DIR*);
281 alias __readdir30 readdir;
282 }
283 else version (OpenBSD)
284 {
285 enum
286 {
287 DT_UNKNOWN = 0,
288 DT_FIFO = 1,
289 DT_CHR = 2,
290 DT_DIR = 4,
291 DT_BLK = 6,
292 DT_REG = 8,
293 DT_LNK = 10,
294 DT_SOCK = 12,
295 }
296
297 alias void* DIR;
298
299 dirent* readdir(DIR*);
300 }
301 else version (DragonFlyBSD)
302 {
303 enum
304 {
305 DT_UNKNOWN = 0,
306 DT_FIFO = 1,
307 DT_CHR = 2,
308 DT_DIR = 4,
309 DT_BLK = 6,
310 DT_REG = 8,
311 DT_LNK = 10,
312 DT_SOCK = 12,
313 DT_WHT = 14,
314 DT_DBF = 15, /* database record file */
315 }
316
317 alias void* DIR;
318
319 dirent* readdir(DIR*);
320 }
321 else version (Solaris)
322 {
323 struct DIR
324 {
325 int dd_fd;
326 int dd_loc;
327 int dd_size;
328 char* dd_buf;
329 }
330
331 version (D_LP64)
332 {
333 dirent* readdir(DIR*);
334 alias readdir64 = readdir;
335 }
336 else
337 {
338 static if (__USE_LARGEFILE64)
339 {
340 dirent* readdir64(DIR*);
341 alias readdir64 readdir;
342 }
343 else
344 {
345 dirent* readdir(DIR*);
346 }
347 }
348 }
349 else version (CRuntime_Bionic)
350 {
351 enum
352 {
353 DT_UNKNOWN = 0,
354 DT_FIFO = 1,
355 DT_CHR = 2,
356 DT_DIR = 4,
357 DT_BLK = 6,
358 DT_REG = 8,
359 DT_LNK = 10,
360 DT_SOCK = 12,
361 DT_WHT = 14
362 }
363
364 struct DIR
365 {
366 }
367
368 dirent* readdir(DIR*);
369 }
370 else version (CRuntime_Musl)
371 {
372 enum
373 {
374 DT_UNKNOWN = 0,
375 DT_FIFO = 1,
376 DT_CHR = 2,
377 DT_DIR = 4,
378 DT_BLK = 6,
379 DT_REG = 8,
380 DT_LNK = 10,
381 DT_SOCK = 12,
382 DT_WHT = 14
383 }
384
385 struct DIR
386 {
387 }
388
389 static if ( __USE_FILE_OFFSET64 )
390 {
391 dirent* readdir64(DIR*);
392 alias readdir64 readdir;
393 }
394 else
395 {
396 dirent* readdir(DIR*);
397 }
398 }
399 else version (CRuntime_UClibc)
400 {
401 // NOTE: The following constants are non-standard Linux definitions
402 // for dirent.d_type.
403 enum
404 {
405 DT_UNKNOWN = 0,
406 DT_FIFO = 1,
407 DT_CHR = 2,
408 DT_DIR = 4,
409 DT_BLK = 6,
410 DT_REG = 8,
411 DT_LNK = 10,
412 DT_SOCK = 12,
413 DT_WHT = 14
414 }
415
416 struct DIR
417 {
418 // Managed by OS
419 }
420
421 static if ( __USE_FILE_OFFSET64 )
422 {
423 dirent* readdir64(DIR*);
424 alias readdir64 readdir;
425 }
426 else
427 {
428 dirent* readdir(DIR*);
429 }
430 }
431 else
432 {
433 static assert(false, "Unsupported platform");
434 }
435
436 // Only OS X out of the Darwin family needs special treatment. Other Darwins
437 // (iOS, TVOS, WatchOS) are fine with normal symbol names for these functions
438 // in else below.
439 version (OSX)
440 {
441 version (AArch64)
442 {
443 int closedir(DIR*);
444 DIR* opendir(const scope char*);
445 void rewinddir(DIR*);
446 }
447 else version (D_LP64)
448 {
449 int closedir(DIR*);
450 pragma(mangle, "opendir$INODE64") DIR* opendir(const scope char*);
451 pragma(mangle, "rewinddir$INODE64") void rewinddir(DIR*);
452 }
453 else
454 {
455 // 32-bit mangles __DARWIN_UNIX03 specific functions with $UNIX2003 to
456 // maintain backward compatibility with binaries build pre 10.5
457 pragma(mangle, "closedir$UNIX2003") int closedir(DIR*);
458 pragma(mangle, "opendir$INODE64$UNIX2003") DIR* opendir(const scope char*);
459 pragma(mangle, "rewinddir$INODE64$UNIX2003") void rewinddir(DIR*);
460 }
461 }
462 else version (NetBSD)
463 {
464 int closedir(DIR*);
465 DIR* __opendir30(const scope char*);
466 alias __opendir30 opendir;
467 void rewinddir(DIR*);
468 }
469 else
470 {
471 int closedir(DIR*);
472 DIR* opendir(const scope char*);
473 //dirent* readdir(DIR*);
474 void rewinddir(DIR*);
475 }
476
477 //
478 // Thread-Safe Functions (TSF)
479 //
480 /*
481 int readdir_r(DIR*, dirent*, dirent**);
482 */
483
484 version (CRuntime_Glibc)
485 {
486 static if ( __USE_LARGEFILE64 )
487 {
488 int readdir64_r(DIR*, dirent*, dirent**);
489 alias readdir64_r readdir_r;
490 }
491 else
492 {
493 int readdir_r(DIR*, dirent*, dirent**);
494 }
495 }
496 else version (Darwin)
497 {
498 version (OSX)
499 pragma(mangle, "readdir_r$INODE64") int readdir_r(DIR*, dirent*, dirent**);
500 else
501 int readdir_r(DIR*, dirent*, dirent**);
502 }
503 else version (FreeBSD)
504 {
505 version (GNU)
506 {
507 int readdir_r(DIR*, dirent*, dirent**);
508 }
509 else
510 {
511 static if (__FreeBSD_version >= 1200000)
512 pragma(mangle, "readdir_r@FBSD_1.5") int readdir_r(DIR*, dirent*, dirent**);
513 else
514 pragma(mangle, "readdir_r@FBSD_1.0") int readdir_r(DIR*, dirent*, dirent**);
515 }
516 }
517 else version (DragonFlyBSD)
518 {
519 int readdir_r(DIR*, dirent*, dirent**);
520 }
521 else version (NetBSD)
522 {
523 int __readdir_r30(DIR*, dirent*, dirent**);
524 alias __readdir_r30 readdir_r;
525 }
526 else version (OpenBSD)
527 {
528 int readdir_r(DIR*, dirent*, dirent**);
529 }
530 else version (Solaris)
531 {
532 static if (__USE_LARGEFILE64)
533 {
534 int readdir64_r(DIR*, dirent*, dirent**);
535 alias readdir64_r readdir_r;
536 }
537 else
538 {
539 int readdir_r(DIR*, dirent*, dirent**);
540 }
541 }
542 else version (CRuntime_Bionic)
543 {
544 int readdir_r(DIR*, dirent*, dirent**);
545 }
546 else version (CRuntime_Musl)
547 {
548 int readdir_r(DIR*, dirent*, dirent**);
549 }
550 else version (CRuntime_UClibc)
551 {
552 static if ( __USE_LARGEFILE64 )
553 {
554 int readdir64_r(DIR*, dirent*, dirent**);
555 alias readdir64_r readdir_r;
556 }
557 else
558 {
559 int readdir_r(DIR*, dirent*, dirent**);
560 }
561 }
562 else
563 {
564 static assert(false, "Unsupported platform");
565 }
566
567 //
568 // XOpen (XSI)
569 //
570 /*
571 void seekdir(DIR*, c_long);
572 c_long telldir(DIR*);
573 */
574
575 version (CRuntime_Glibc)
576 {
577 void seekdir(DIR*, c_long);
578 c_long telldir(DIR*);
579 }
580 else version (FreeBSD)
581 {
582 version (GNU)
583 {
584 void seekdir(DIR*, c_long);
585 c_long telldir(DIR*);
586 }
587 else
588 {
589 pragma(mangle, "seekdir@@FBSD_1.0") void seekdir(DIR*, c_long);
590 pragma(mangle, "telldir@@FBSD_1.0") c_long telldir(DIR*);
591 }
592 }
593 else version (NetBSD)
594 {
595 void seekdir(DIR*, c_long);
596 c_long telldir(DIR*);
597 }
598 else version (OpenBSD)
599 {
600 void seekdir(DIR*, c_long);
601 c_long telldir(DIR*);
602 }
603 else version (DragonFlyBSD)
604 {
605 void seekdir(DIR*, c_long);
606 c_long telldir(DIR*);
607 }
608 else version (Darwin)
609 {
610 version (OSX)
611 {
612 version (D_LP64)
613 {
614 pragma(mangle, "seekdir$INODE64") void seekdir(DIR*, c_long);
615 pragma(mangle, "telldir$INODE64") c_long telldir(DIR*);
616 }
617 else
618 {
619 // 32-bit mangles __DARWIN_UNIX03 specific functions with $UNIX2003 to
620 // maintain backward compatibility with binaries build pre 10.5
621 pragma(mangle, "seekdir$INODE64$UNIX2003") void seekdir(DIR*, c_long);
622 pragma(mangle, "telldir$INODE64$UNIX2003") c_long telldir(DIR*);
623 }
624 }
625 else // other Darwins (e.g. iOS, TVOS, WatchOS)
626 {
627 void seekdir(DIR*, c_long);
628 c_long telldir(DIR*);
629 }
630 }
631 else version (Solaris)
632 {
633 c_long telldir(DIR*);
634 void seekdir(DIR*, c_long);
635 }
636 else version (CRuntime_Bionic)
637 {
638 }
639 else version (CRuntime_Musl)
640 {
641 void seekdir(DIR*, c_long);
642 c_long telldir(DIR*);
643 }
644 else version (CRuntime_UClibc)
645 {
646 void seekdir(DIR*, c_long);
647 c_long telldir(DIR*);
648 }
649 else
650 {
651 static assert(false, "Unsupported platform");
652 }
653