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 }