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 dirent* readdir(DIR*); 389 alias readdir64 = readdir; 390 } 391 else version (CRuntime_UClibc) 392 { 393 // NOTE: The following constants are non-standard Linux definitions 394 // for dirent.d_type. 395 enum 396 { 397 DT_UNKNOWN = 0, 398 DT_FIFO = 1, 399 DT_CHR = 2, 400 DT_DIR = 4, 401 DT_BLK = 6, 402 DT_REG = 8, 403 DT_LNK = 10, 404 DT_SOCK = 12, 405 DT_WHT = 14 406 } 407 408 struct DIR 409 { 410 // Managed by OS 411 } 412 413 static if ( __USE_FILE_OFFSET64 ) 414 { 415 dirent* readdir64(DIR*); 416 alias readdir64 readdir; 417 } 418 else 419 { 420 dirent* readdir(DIR*); 421 } 422 } 423 else 424 { 425 static assert(false, "Unsupported platform"); 426 } 427 428 // Only OS X out of the Darwin family needs special treatment. Other Darwins 429 // (iOS, TVOS, WatchOS) are fine with normal symbol names for these functions 430 // in else below. 431 version (OSX) 432 { 433 version (AArch64) 434 { 435 int closedir(DIR*); 436 DIR* opendir(const scope char*); 437 void rewinddir(DIR*); 438 } 439 else version (D_LP64) 440 { 441 int closedir(DIR*); 442 pragma(mangle, "opendir$INODE64") DIR* opendir(const scope char*); 443 pragma(mangle, "rewinddir$INODE64") void rewinddir(DIR*); 444 } 445 else 446 { 447 // 32-bit mangles __DARWIN_UNIX03 specific functions with $UNIX2003 to 448 // maintain backward compatibility with binaries build pre 10.5 449 pragma(mangle, "closedir$UNIX2003") int closedir(DIR*); 450 pragma(mangle, "opendir$INODE64$UNIX2003") DIR* opendir(const scope char*); 451 pragma(mangle, "rewinddir$INODE64$UNIX2003") void rewinddir(DIR*); 452 } 453 } 454 else version (NetBSD) 455 { 456 int closedir(DIR*); 457 DIR* __opendir30(const scope char*); 458 alias __opendir30 opendir; 459 void rewinddir(DIR*); 460 } 461 else 462 { 463 int closedir(DIR*); 464 DIR* opendir(const scope char*); 465 //dirent* readdir(DIR*); 466 void rewinddir(DIR*); 467 } 468 469 // 470 // Thread-Safe Functions (TSF) 471 // 472 /* 473 int readdir_r(DIR*, dirent*, dirent**); 474 */ 475 476 version (CRuntime_Glibc) 477 { 478 static if ( __USE_LARGEFILE64 ) 479 { 480 int readdir64_r(DIR*, dirent*, dirent**); 481 alias readdir64_r readdir_r; 482 } 483 else 484 { 485 int readdir_r(DIR*, dirent*, dirent**); 486 } 487 } 488 else version (Darwin) 489 { 490 version (OSX) 491 pragma(mangle, "readdir_r$INODE64") int readdir_r(DIR*, dirent*, dirent**); 492 else 493 int readdir_r(DIR*, dirent*, dirent**); 494 } 495 else version (FreeBSD) 496 { 497 version (GNU) 498 { 499 int readdir_r(DIR*, dirent*, dirent**); 500 } 501 else 502 { 503 static if (__FreeBSD_version >= 1200000) 504 pragma(mangle, "readdir_r@FBSD_1.5") int readdir_r(DIR*, dirent*, dirent**); 505 else 506 pragma(mangle, "readdir_r@FBSD_1.0") int readdir_r(DIR*, dirent*, dirent**); 507 } 508 } 509 else version (DragonFlyBSD) 510 { 511 int readdir_r(DIR*, dirent*, dirent**); 512 } 513 else version (NetBSD) 514 { 515 int __readdir_r30(DIR*, dirent*, dirent**); 516 alias __readdir_r30 readdir_r; 517 } 518 else version (OpenBSD) 519 { 520 int readdir_r(DIR*, dirent*, dirent**); 521 } 522 else version (Solaris) 523 { 524 static if (__USE_LARGEFILE64) 525 { 526 int readdir64_r(DIR*, dirent*, dirent**); 527 alias readdir64_r readdir_r; 528 } 529 else 530 { 531 int readdir_r(DIR*, dirent*, dirent**); 532 } 533 } 534 else version (CRuntime_Bionic) 535 { 536 int readdir_r(DIR*, dirent*, dirent**); 537 } 538 else version (CRuntime_Musl) 539 { 540 int readdir_r(DIR*, dirent*, dirent**); 541 } 542 else version (CRuntime_UClibc) 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 555 { 556 static assert(false, "Unsupported platform"); 557 } 558 559 // 560 // XOpen (XSI) 561 // 562 /* 563 void seekdir(DIR*, c_long); 564 c_long telldir(DIR*); 565 */ 566 567 version (CRuntime_Glibc) 568 { 569 void seekdir(DIR*, c_long); 570 c_long telldir(DIR*); 571 } 572 else version (FreeBSD) 573 { 574 version (GNU) 575 { 576 void seekdir(DIR*, c_long); 577 c_long telldir(DIR*); 578 } 579 else 580 { 581 pragma(mangle, "seekdir@@FBSD_1.0") void seekdir(DIR*, c_long); 582 pragma(mangle, "telldir@@FBSD_1.0") c_long telldir(DIR*); 583 } 584 } 585 else version (NetBSD) 586 { 587 void seekdir(DIR*, c_long); 588 c_long telldir(DIR*); 589 } 590 else version (OpenBSD) 591 { 592 void seekdir(DIR*, c_long); 593 c_long telldir(DIR*); 594 } 595 else version (DragonFlyBSD) 596 { 597 void seekdir(DIR*, c_long); 598 c_long telldir(DIR*); 599 } 600 else version (Darwin) 601 { 602 version (OSX) 603 { 604 version (D_LP64) 605 { 606 pragma(mangle, "seekdir$INODE64") void seekdir(DIR*, c_long); 607 pragma(mangle, "telldir$INODE64") c_long telldir(DIR*); 608 } 609 else 610 { 611 // 32-bit mangles __DARWIN_UNIX03 specific functions with $UNIX2003 to 612 // maintain backward compatibility with binaries build pre 10.5 613 pragma(mangle, "seekdir$INODE64$UNIX2003") void seekdir(DIR*, c_long); 614 pragma(mangle, "telldir$INODE64$UNIX2003") c_long telldir(DIR*); 615 } 616 } 617 else // other Darwins (e.g. iOS, TVOS, WatchOS) 618 { 619 void seekdir(DIR*, c_long); 620 c_long telldir(DIR*); 621 } 622 } 623 else version (Solaris) 624 { 625 c_long telldir(DIR*); 626 void seekdir(DIR*, c_long); 627 } 628 else version (CRuntime_Bionic) 629 { 630 } 631 else version (CRuntime_Musl) 632 { 633 void seekdir(DIR*, c_long); 634 c_long telldir(DIR*); 635 } 636 else version (CRuntime_UClibc) 637 { 638 void seekdir(DIR*, c_long); 639 c_long telldir(DIR*); 640 } 641 else 642 { 643 static assert(false, "Unsupported platform"); 644 }