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