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