1 /** 2 * D header file for C99 <stdio.h> 3 * 4 * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_stdio.h.html, _stdio.h) 5 * 6 * Copyright: Copyright Sean Kelly 2005 - 2009. 7 * License: Distributed under the 8 * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0). 9 * (See accompanying file LICENSE) 10 * Authors: Sean Kelly, 11 * Alex Rønne Petersen 12 * Source: https://github.com/dlang/dmd/blob/master/druntime/src/core/stdc/stdio.d 13 * Standards: ISO/IEC 9899:1999 (E) 14 */ 15 16 module core.stdc.stdio; 17 18 version (OSX) 19 version = Darwin; 20 else version (iOS) 21 version = Darwin; 22 else version (TVOS) 23 version = Darwin; 24 else version (WatchOS) 25 version = Darwin; 26 27 version (FreeStanding) 28 { 29 struct FILE {} 30 alias fpos_t = long; 31 } 32 33 private 34 { 35 import core.stdc.config; 36 import core.stdc.stdarg; // for va_list 37 import core.stdc.stdint : intptr_t; 38 39 version (FreeBSD) 40 { 41 import core.sys.posix.sys.types; 42 } 43 else version (OpenBSD) 44 { 45 import core.sys.posix.sys.types; 46 } 47 version (NetBSD) 48 { 49 import core.sys.posix.sys.types; 50 } 51 version (DragonFlyBSD) 52 { 53 import core.sys.posix.sys.types; 54 } 55 } 56 57 extern (C): 58 nothrow: 59 @nogc: 60 61 version (CRuntime_DigitalMars) 62 { 63 enum 64 { 65 /// 66 BUFSIZ = 0x4000, 67 /// 68 EOF = -1, 69 /// 70 FOPEN_MAX = 20, 71 /// 72 FILENAME_MAX = 256, // 255 plus NULL 73 /// 74 TMP_MAX = 32767, 75 /// 76 SYS_OPEN = 20, // non-standard 77 } 78 79 /// 80 enum int _NFILE = 60; // non-standard 81 /// 82 enum string _P_tmpdir = "\\"; // non-standard 83 /// 84 enum wstring _wP_tmpdir = "\\"; // non-standard 85 /// 86 enum int L_tmpnam = _P_tmpdir.length + 12; 87 } 88 else version (CRuntime_Microsoft) 89 { 90 enum 91 { 92 /// 93 BUFSIZ = 512, 94 /// 95 EOF = -1, 96 /// 97 FOPEN_MAX = 20, 98 /// 99 FILENAME_MAX = 260, 100 /// Actually int.max since Visual Studio 2015. 101 TMP_MAX = 32767, 102 /// 103 _SYS_OPEN = 20, // non-standard 104 } 105 106 /// 107 enum int _NFILE = 512; // non-standard 108 /// Removed since Visual Studio 2015. 109 enum string _P_tmpdir = "\\"; // non-standard 110 /// Removed since Visual Studio 2015. 111 enum wstring _wP_tmpdir = "\\"; // non-standard 112 /// Actually 260 since Visual Studio 2015. 113 enum int L_tmpnam = _P_tmpdir.length + 12; 114 } 115 else version (CRuntime_Glibc) 116 { 117 enum 118 { 119 /// 120 BUFSIZ = 8192, 121 /// 122 EOF = -1, 123 /// 124 FOPEN_MAX = 16, 125 /// 126 FILENAME_MAX = 4095, 127 /// 128 TMP_MAX = 238328, 129 /// 130 L_tmpnam = 20 131 } 132 } 133 else version (CRuntime_Musl) 134 { 135 enum 136 { 137 /// 138 BUFSIZ = 1024, 139 /// 140 EOF = -1, 141 /// 142 FOPEN_MAX = 1000, 143 /// 144 FILENAME_MAX = 4096, 145 /// 146 TMP_MAX = 10000, 147 /// 148 L_tmpnam = 20 149 } 150 } 151 else version (Darwin) 152 { 153 enum 154 { 155 /// 156 BUFSIZ = 1024, 157 /// 158 EOF = -1, 159 /// 160 FOPEN_MAX = 20, 161 /// 162 FILENAME_MAX = 1024, 163 /// 164 TMP_MAX = 308915776, 165 /// 166 L_tmpnam = 1024, 167 } 168 169 private 170 { 171 struct __sbuf 172 { 173 ubyte* _base; 174 int _size; 175 } 176 177 struct __sFILEX 178 { 179 180 } 181 } 182 } 183 else version (FreeBSD) 184 { 185 enum 186 { 187 /// 188 BUFSIZ = 1024, 189 /// 190 EOF = -1, 191 /// 192 FOPEN_MAX = 20, 193 /// 194 FILENAME_MAX = 1024, 195 /// 196 TMP_MAX = 308915776, 197 /// 198 L_tmpnam = 1024 199 } 200 201 struct __sbuf 202 { 203 ubyte *_base; 204 int _size; 205 } 206 } 207 else version (NetBSD) 208 { 209 enum 210 { 211 /// 212 BUFSIZ = 1024, 213 /// 214 EOF = -1, 215 /// 216 FOPEN_MAX = 20, 217 /// 218 FILENAME_MAX = 1024, 219 /// 220 TMP_MAX = 308915776, 221 /// 222 L_tmpnam = 1024 223 } 224 225 struct __sbuf 226 { 227 ubyte *_base; 228 int _size; 229 } 230 } 231 else version (OpenBSD) 232 { 233 enum 234 { 235 /// 236 BUFSIZ = 1024, 237 /// 238 EOF = -1, 239 /// 240 FOPEN_MAX = 20, 241 /// 242 FILENAME_MAX = 1024, 243 /// 244 TMP_MAX = 0x7fffffff, 245 /// 246 L_tmpnam = 1024 247 } 248 249 struct __sbuf 250 { 251 ubyte *_base; 252 int _size; 253 } 254 } 255 else version (DragonFlyBSD) 256 { 257 enum 258 { 259 BUFSIZ = 1024, 260 EOF = -1, 261 FOPEN_MAX = 20, 262 FILENAME_MAX = 1024, 263 TMP_MAX = 308915776, 264 L_tmpnam = 1024 265 } 266 267 struct __sbuf { // <sys/sbuf.h> 268 byte* s_buf; // storage buffer 269 int function(void *, const char *, int) sbuf_drain_func; 270 void* s_drain_arg; // user-supplied drain argument 271 int s_error; // current error code 272 ssize_t s_size; // size of storage buffer 273 ssize_t s_len; // current length of string 274 int s_flags; // flags 275 ssize_t s_sect_len; // current length of section 276 } 277 278 enum { 279 SBUF_FIXEDLEN = 0x00000000, // fixed length buffer (default) 280 SBUF_AUTOEXTEND = 0x00000001, // automatically extend buffer 281 SBUF_USRFLAGMSK = 0x0000ffff, // mask of flags the user may specify 282 SBUF_DYNAMIC = 0x00010000, // s_buf must be freed 283 SBUF_FINISHED = 0x00020000, // set by sbuf_finish() 284 SBUF_DYNSTRUCT = 0x00080000, // sbuf must be freed 285 SBUF_INSECTION = 0x00100000, // set by sbuf_start_section() 286 } 287 } 288 else version (Solaris) 289 { 290 enum 291 { 292 /// 293 BUFSIZ = 1024, 294 /// 295 EOF = -1, 296 /// 297 FOPEN_MAX = _NFILE, 298 /// 299 FILENAME_MAX = 1024, 300 /// 301 TMP_MAX = 17576, 302 /// 303 L_tmpnam = 25, 304 } 305 306 version (X86) 307 /// 308 enum int _NFILE = 60; 309 else 310 /// 311 enum int _NFILE = 20; 312 } 313 else version (CRuntime_Bionic) 314 { 315 enum 316 { 317 /// 318 BUFSIZ = 1024, 319 /// 320 EOF = -1, 321 /// 322 FOPEN_MAX = 20, 323 /// 324 FILENAME_MAX = 1024, 325 /// 326 TMP_MAX = 308915776, 327 /// 328 L_tmpnam = 1024 329 } 330 331 struct __sbuf 332 { 333 ubyte* _base; 334 int _size; 335 } 336 } 337 else version (CRuntime_UClibc) 338 { 339 enum 340 { 341 /// 342 BUFSIZ = 4096, 343 /// 344 EOF = -1, 345 /// 346 FOPEN_MAX = 16, 347 /// 348 FILENAME_MAX = 4095, 349 /// 350 TMP_MAX = 238328, 351 /// 352 L_tmpnam = 20 353 } 354 } 355 else version (WASI) 356 { 357 enum 358 { 359 /// 360 BUFSIZ = 1024, 361 /// 362 EOF = -1, 363 /// 364 FOPEN_MAX = 1000, 365 /// 366 FILENAME_MAX = 4096, 367 /// 368 TMP_MAX = 10000, 369 /// 370 L_tmpnam = 20 371 } 372 } 373 else version (FreeStanding) {} 374 else 375 { 376 static assert( false, "Unsupported platform" ); 377 } 378 379 enum 380 { 381 /// Offset is relative to the beginning 382 SEEK_SET, 383 /// Offset is relative to the current position 384 SEEK_CUR, 385 /// Offset is relative to the end 386 SEEK_END 387 } 388 389 version (CRuntime_DigitalMars) 390 { 391 /// 392 alias c_long fpos_t; 393 394 /// 395 struct _iobuf 396 { 397 char* _ptr; 398 int _cnt; 399 char* _base; 400 int _flag; 401 int _file; 402 int _charbuf; 403 int _bufsiz; 404 char* __tmpnum; 405 } 406 407 /// 408 alias shared(_iobuf) FILE; 409 } 410 else version (CRuntime_Microsoft) 411 { 412 /// 413 alias long fpos_t; 414 415 /// 416 struct _iobuf 417 { 418 void* undefined; 419 } 420 421 /// 422 alias shared(_iobuf) FILE; 423 } 424 else version (CRuntime_Glibc) 425 { 426 import core.stdc.wchar_ : mbstate_t; 427 /// 428 struct fpos_t 429 { 430 long __pos; // couldn't use off_t because of static if issue 431 mbstate_t __state; 432 } 433 434 /// 435 struct _IO_FILE 436 { 437 int _flags; 438 char* _read_ptr; 439 char* _read_end; 440 char* _read_base; 441 char* _write_base; 442 char* _write_ptr; 443 char* _write_end; 444 char* _buf_base; 445 char* _buf_end; 446 char* _save_base; 447 char* _backup_base; 448 char* _save_end; 449 void* _markers; 450 _IO_FILE* _chain; 451 int _fileno; 452 int _flags2; 453 ptrdiff_t _old_offset; 454 ushort _cur_column; 455 byte _vtable_offset; 456 char[1] _shortbuf = 0; 457 void* _lock; 458 459 ptrdiff_t _offset; 460 461 /*_IO_codecvt*/ void* _codecvt; 462 /*_IO_wide_data*/ void* _wide_data; 463 _IO_FILE *_freeres_list; 464 void *_freeres_buf; 465 size_t __pad5; 466 int _mode; 467 468 char[15 * int.sizeof - 4 * (void*).sizeof - size_t.sizeof] _unused2; 469 } 470 471 /// 472 alias _IO_FILE _iobuf; 473 /// 474 alias shared(_IO_FILE) FILE; 475 } 476 else version (WASI) 477 { 478 union fpos_t 479 { 480 char[16] __opaque = 0; 481 double __align; 482 } 483 struct _IO_FILE; 484 485 /// 486 alias _IO_FILE _iobuf; // needed for phobos 487 /// 488 alias shared(_IO_FILE) FILE; 489 } 490 else version (CRuntime_Musl) 491 { 492 union fpos_t 493 { 494 char[16] __opaque = 0; 495 double __align; 496 } 497 struct _IO_FILE; 498 499 /// 500 alias _IO_FILE _iobuf; // needed for phobos 501 /// 502 alias shared(_IO_FILE) FILE; 503 } 504 else version (Darwin) 505 { 506 /// 507 alias long fpos_t; 508 509 /// 510 struct __sFILE 511 { 512 ubyte* _p; 513 int _r; 514 int _w; 515 short _flags; 516 short _file; 517 __sbuf _bf; 518 int _lbfsize; 519 520 void* _cookie; 521 int function(void*) _close; 522 int function(void*, char*, int) _read; 523 fpos_t function(void*, fpos_t, int) _seek; 524 int function(void*, char *, int) _write; 525 526 __sbuf _ub; 527 __sFILEX* _extra; 528 int _ur; 529 530 ubyte[3] _ubuf; 531 ubyte[1] _nbuf; 532 533 __sbuf _lb; 534 535 int _blksize; 536 fpos_t _offset; 537 } 538 539 /// 540 alias __sFILE _iobuf; 541 /// 542 alias shared(__sFILE) FILE; 543 } 544 else version (FreeBSD) 545 { 546 // Need to import wchar_ now since __mbstate_t now resides there 547 import core.stdc.wchar_ : mbstate_t; 548 549 /// 550 alias off_t fpos_t; 551 552 /// 553 struct __sFILE 554 { 555 ubyte* _p; 556 int _r; 557 int _w; 558 short _flags; 559 short _file; 560 __sbuf _bf; 561 int _lbfsize; 562 563 void* _cookie; 564 int function(void*) _close; 565 int function(void*, char*, int) _read; 566 fpos_t function(void*, fpos_t, int) _seek; 567 int function(void*, const scope char*, int) _write; 568 569 __sbuf _ub; 570 ubyte* _up; 571 int _ur; 572 573 ubyte[3] _ubuf; 574 ubyte[1] _nbuf; 575 576 __sbuf _lb; 577 578 int _blksize; 579 fpos_t _offset; 580 581 pthread_mutex_t _fl_mutex; 582 pthread_t _fl_owner; 583 int _fl_count; 584 int _orientation; 585 mbstate_t _mbstate; 586 } 587 588 /// 589 alias __sFILE _iobuf; 590 /// 591 alias shared(__sFILE) FILE; 592 } 593 else version (NetBSD) 594 { 595 /// 596 alias off_t fpos_t; 597 598 /// 599 struct __sFILE 600 { 601 ubyte* _p; 602 int _r; 603 int _w; 604 ushort _flags; 605 short _file; 606 __sbuf _bf; 607 int _lbfsize; 608 609 void* _cookie; 610 int function(void*) _close; 611 ssize_t function(void*, char*, size_t) _read; 612 fpos_t function(void*, fpos_t, int) _seek; 613 ssize_t function(void*, const scope char*, size_t) _write; 614 615 __sbuf _ub; 616 ubyte* _up; 617 int _ur; 618 619 ubyte[3] _ubuf; 620 ubyte[1] _nbuf; 621 622 int function(void *) _flush; 623 /* Formerly used by fgetln/fgetwln; kept for binary compatibility */ 624 char[__sbuf.sizeof - _flush.sizeof] _lb_unused = void; 625 626 627 int _blksize; 628 off_t _offset; 629 static assert(off_t.sizeof==8); 630 } 631 632 /// 633 alias __sFILE _iobuf; 634 /// 635 alias shared(__sFILE) FILE; 636 } 637 else version (OpenBSD) 638 { 639 /// 640 alias fpos_t = off_t; 641 642 /// 643 struct __sFILE 644 { 645 ubyte* _p; 646 int _r; 647 int _w; 648 short _flags; 649 short _file; 650 __sbuf _bf; 651 int _lbfsize; 652 653 void* _cookie; 654 int function(void*) _close; 655 int function(void*, scope char*, int) _read; 656 fpos_t function(void*, fpos_t, int) _seek; 657 int function(void*, scope const char*, int) _write; 658 659 __sbuf _ext; 660 ubyte* _up; 661 int _ur; 662 663 ubyte[3] _ubuf; 664 ubyte[1] _nbuf; 665 666 __sbuf _lb; 667 668 int _blksize; 669 fpos_t _offset; 670 } 671 672 /// 673 alias __sFILE _iobuf; 674 /// 675 alias shared(__sFILE) FILE; 676 } 677 else version (DragonFlyBSD) 678 { 679 alias off_t fpos_t; 680 681 /// See /usr/include/stdio.h 682 struct __FILE_public 683 { 684 ubyte* *_p; /* current position in (some) buffer */ 685 int _flags; /* flags, below; this FILE is free if 0 */ 686 int _fileno; /* fileno, if Unix descriptor, else -1 */ 687 ssize_t _r; /* read space left for getc() */ 688 ssize_t _w; /* write space left for putc() */ 689 ssize_t _lbfsize; /* 0 or -_bf._size, for inline putc */ 690 } 691 692 alias __FILE_public _iobuf; 693 alias shared(__FILE_public) FILE; 694 } 695 else version (Solaris) 696 { 697 import core.stdc.wchar_ : mbstate_t; 698 699 /// 700 alias c_long fpos_t; 701 702 version (D_LP64) 703 { 704 /// 705 struct _iobuf 706 { 707 char* _ptr; /* next character from/to here in buffer */ 708 char* _base; /* the buffer */ 709 char* _end; /* the end of the buffer */ 710 size_t _cnt; /* number of available characters in buffer */ 711 int _file; /* UNIX System file descriptor */ 712 int _flag; /* the state of the stream */ 713 ubyte[24] _lock; //rmutex_t _lock; /* lock for this structure */ 714 mbstate_t _state; /* mbstate_t */ 715 ubyte[32] __fill; /* filler to bring size to 128 bytes */ 716 } 717 } 718 else 719 { 720 /// 721 struct _iobuf 722 { 723 char* _ptr; 724 int _cnt; 725 char* _base; 726 char _flag = 0; 727 char _magic = 0; 728 ushort __flags; // __orientation:2 729 // __ionolock:1 730 // __seekable:1 731 // __extendedfd:1 732 // __xf_nocheck:1 733 // __filler:10 734 } 735 } 736 /// 737 alias shared(_iobuf) FILE; 738 } 739 else version (CRuntime_Bionic) 740 { 741 /// 742 alias c_long fpos_t; // couldn't use off_t because of static if issue 743 744 /// 745 struct __sFILE 746 { 747 ubyte* _p; 748 int _r; 749 int _w; 750 short _flags; 751 short _file; 752 __sbuf _bf; 753 int _lbfsize; 754 755 void* _cookie; 756 int function(void*) _close; 757 int function(void*, scope char*, int) _read; 758 fpos_t function(void*, fpos_t, int) _seek; 759 int function(void*, scope const char*, int) _write; 760 761 __sbuf _ext; 762 ubyte* _up; 763 int _ur; 764 765 ubyte[3] _ubuf; 766 ubyte[1] _nbuf; 767 768 __sbuf _lb; 769 770 int _blksize; 771 fpos_t _offset; 772 } 773 774 /// 775 alias __sFILE _iobuf; 776 /// 777 alias shared(__sFILE) FILE; 778 } 779 else version (CRuntime_UClibc) 780 { 781 import core.stdc.wchar_ : mbstate_t; 782 import core.stdc.stddef : wchar_t; 783 import core.sys.posix.sys.types : ssize_t, pthread_mutex_t; 784 785 /// 786 struct fpos_t 787 { 788 long __pos; // couldn't use off_t because of static if issue 789 mbstate_t __state; 790 int __mblen_pending; 791 } 792 793 struct _IO_cookie_io_functions_t 794 { 795 ssize_t function(void* __cookie, char* __buf, size_t __bufsize) read; 796 ssize_t function(void* __cookie, const char* __buf, size_t __bufsize) write; 797 int function(void* __cookie, long* __pos, int __whence) seek; 798 int function(void* __cookie) close; 799 } 800 801 alias _IO_cookie_io_functions_t cookie_io_functions_t; 802 803 /// 804 struct __STDIO_FILE_STRUCT 805 { 806 ushort __modeflags; 807 char[2] __ungot_width = 0; 808 int __filedes; 809 char* __bufstart; 810 char* __bufend; 811 char* __bufpos; 812 char* __bufread; 813 char* __bufgetc_u; 814 char*__bufputc_u; 815 __STDIO_FILE_STRUCT* __nextopen; 816 void *__cookie; 817 _IO_cookie_io_functions_t __gcs; 818 wchar_t[2] __ungot = 0; 819 mbstate_t __state; 820 void *__unused; 821 int __user_locking; 822 pthread_mutex_t __lock; 823 } 824 825 /// 826 alias __STDIO_FILE_STRUCT _iobuf; 827 /// 828 alias shared(__STDIO_FILE_STRUCT) FILE; 829 } 830 else version (FreeStanding) 831 { 832 } 833 else 834 { 835 static assert( false, "Unsupported platform" ); 836 } 837 838 enum 839 { 840 /// 841 _F_RDWR = 0x0003, // non-standard 842 /// 843 _F_READ = 0x0001, // non-standard 844 /// 845 _F_WRIT = 0x0002, // non-standard 846 /// 847 _F_BUF = 0x0004, // non-standard 848 /// 849 _F_LBUF = 0x0008, // non-standard 850 /// 851 _F_ERR = 0x0010, // non-standard 852 /// 853 _F_EOF = 0x0020, // non-standard 854 /// 855 _F_BIN = 0x0040, // non-standard 856 /// 857 _F_IN = 0x0080, // non-standard 858 /// 859 _F_OUT = 0x0100, // non-standard 860 /// 861 _F_TERM = 0x0200, // non-standard 862 } 863 864 version (CRuntime_DigitalMars) 865 { 866 enum 867 { 868 /// 869 _IOFBF = 0, 870 /// 871 _IOLBF = 0x40, 872 /// 873 _IONBF = 4, 874 /// 875 _IOREAD = 1, // non-standard 876 /// 877 _IOWRT = 2, // non-standard 878 /// 879 _IOMYBUF = 8, // non-standard 880 /// 881 _IOEOF = 0x10, // non-standard 882 /// 883 _IOERR = 0x20, // non-standard 884 /// 885 _IOSTRG = 0x40, // non-standard 886 /// 887 _IORW = 0x80, // non-standard 888 /// 889 _IOTRAN = 0x100, // non-standard 890 /// 891 _IOAPP = 0x200, // non-standard 892 } 893 894 extern shared void function() _fcloseallp; 895 896 private extern shared FILE[_NFILE] _iob; 897 898 /// 899 enum stdin = &_iob[0]; 900 /// 901 enum stdout = &_iob[1]; 902 /// 903 enum stderr = &_iob[2]; 904 /// 905 enum stdaux = &_iob[3]; 906 /// 907 enum stdprn = &_iob[4]; 908 } 909 else version (CRuntime_Microsoft) 910 { 911 enum 912 { 913 /// 914 _IOFBF = 0, 915 /// 916 _IOLBF = 0x40, 917 /// 918 _IONBF = 4, 919 /// Removed since Visual Studio 2015. 920 _IOREAD = 1, // non-standard 921 /// Removed since Visual Studio 2015. 922 _IOWRT = 2, // non-standard 923 /// Removed since Visual Studio 2015. 924 _IOMYBUF = 8, // non-standard 925 /// Removed since Visual Studio 2015. 926 _IOEOF = 0x10, // non-standard 927 /// Removed since Visual Studio 2015. 928 _IOERR = 0x20, // non-standard 929 /// Removed since Visual Studio 2015. 930 _IOSTRG = 0x40, // non-standard 931 /// Removed since Visual Studio 2015. 932 _IORW = 0x80, // non-standard 933 /// Removed since Visual Studio 2015. 934 _IOAPP = 0x200, // non-standard 935 /// Removed since Visual Studio 2015. 936 _IOAPPEND = 0x200, // non-standard 937 } 938 939 extern shared void function() _fcloseallp; 940 941 FILE* __acrt_iob_func(int hnd); // VS2015+, reimplemented in msvc.d for VS2013- 942 943 /// 944 FILE* stdin()() { return __acrt_iob_func(0); } 945 /// 946 FILE* stdout()() { return __acrt_iob_func(1); } 947 /// 948 FILE* stderr()() { return __acrt_iob_func(2); } 949 } 950 else version (CRuntime_Glibc) 951 { 952 enum 953 { 954 /// 955 _IOFBF = 0, 956 /// 957 _IOLBF = 1, 958 /// 959 _IONBF = 2, 960 } 961 962 /// 963 extern shared FILE* stdin; 964 /// 965 extern shared FILE* stdout; 966 /// 967 extern shared FILE* stderr; 968 } 969 else version (Darwin) 970 { 971 enum 972 { 973 /// 974 _IOFBF = 0, 975 /// 976 _IOLBF = 1, 977 /// 978 _IONBF = 2, 979 } 980 981 private extern shared FILE* __stdinp; 982 private extern shared FILE* __stdoutp; 983 private extern shared FILE* __stderrp; 984 985 /// 986 alias __stdinp stdin; 987 /// 988 alias __stdoutp stdout; 989 /// 990 alias __stderrp stderr; 991 } 992 else version (FreeBSD) 993 { 994 enum 995 { 996 /// 997 _IOFBF = 0, 998 /// 999 _IOLBF = 1, 1000 /// 1001 _IONBF = 2, 1002 } 1003 1004 private extern shared FILE* __stdinp; 1005 private extern shared FILE* __stdoutp; 1006 private extern shared FILE* __stderrp; 1007 1008 /// 1009 alias __stdinp stdin; 1010 /// 1011 alias __stdoutp stdout; 1012 /// 1013 alias __stderrp stderr; 1014 } 1015 else version (NetBSD) 1016 { 1017 enum 1018 { 1019 /// 1020 _IOFBF = 0, 1021 /// 1022 _IOLBF = 1, 1023 /// 1024 _IONBF = 2, 1025 } 1026 1027 private extern shared FILE[3] __sF; 1028 @property auto __stdin()() { return &__sF[0]; } 1029 @property auto __stdout()() { return &__sF[1]; } 1030 @property auto __stderr()() { return &__sF[2]; } 1031 /// 1032 alias __stdin stdin; 1033 /// 1034 alias __stdout stdout; 1035 /// 1036 alias __stderr stderr; 1037 } 1038 else version (OpenBSD) 1039 { 1040 enum 1041 { 1042 /// 1043 _IOFBF = 0, 1044 /// 1045 _IOLBF = 1, 1046 /// 1047 _IONBF = 2, 1048 } 1049 1050 private extern shared FILE[3] __sF; 1051 @property auto __stdin()() { return &__sF[0]; } 1052 @property auto __stdout()() { return &__sF[1]; } 1053 @property auto __stderr()() { return &__sF[2]; } 1054 /// 1055 alias __stdin stdin; 1056 /// 1057 alias __stdout stdout; 1058 /// 1059 alias __stderr stderr; 1060 } 1061 else version (DragonFlyBSD) 1062 { 1063 enum 1064 { 1065 _IOFBF = 0, 1066 _IOLBF = 1, 1067 _IONBF = 2, 1068 } 1069 1070 private extern shared FILE* __stdinp; 1071 private extern shared FILE* __stdoutp; 1072 private extern shared FILE* __stderrp; 1073 1074 alias __stdinp stdin; 1075 alias __stdoutp stdout; 1076 alias __stderrp stderr; 1077 } 1078 else version (Solaris) 1079 { 1080 enum 1081 { 1082 /// 1083 _IOFBF = 0x00, 1084 /// 1085 _IOLBF = 0x40, 1086 /// 1087 _IONBF = 0x04, 1088 /// 1089 _IOEOF = 0x20, 1090 /// 1091 _IOERR = 0x40, 1092 /// 1093 _IOREAD = 0x01, 1094 /// 1095 _IOWRT = 0x02, 1096 /// 1097 _IORW = 0x80, 1098 /// 1099 _IOMYBUF = 0x08, 1100 } 1101 1102 private extern shared FILE[_NFILE] __iob; 1103 1104 /// 1105 @property auto stdin()() { return &__iob[0]; } 1106 /// 1107 @property auto stdout()() { return &__iob[1]; } 1108 /// 1109 @property auto stderr()() { return &__iob[2]; } 1110 } 1111 else version (CRuntime_Bionic) 1112 { 1113 enum 1114 { 1115 /// 1116 _IOFBF = 0, 1117 /// 1118 _IOLBF = 1, 1119 /// 1120 _IONBF = 2, 1121 } 1122 1123 private extern shared FILE[3] __sF; 1124 1125 /// 1126 @property auto stdin()() { return &__sF[0]; } 1127 /// 1128 @property auto stdout()() { return &__sF[1]; } 1129 /// 1130 @property auto stderr()() { return &__sF[2]; } 1131 } 1132 else version (CRuntime_Musl) 1133 { 1134 // needs tail const 1135 extern shared FILE* stdin; 1136 /// 1137 extern shared FILE* stdout; 1138 /// 1139 extern shared FILE* stderr; 1140 enum 1141 { 1142 /// 1143 _IOFBF = 0, 1144 /// 1145 _IOLBF = 1, 1146 /// 1147 _IONBF = 2, 1148 } 1149 } 1150 else version (CRuntime_UClibc) 1151 { 1152 enum 1153 { 1154 /// 1155 _IOFBF = 0, 1156 /// 1157 _IOLBF = 1, 1158 /// 1159 _IONBF = 2, 1160 } 1161 1162 /// 1163 extern shared FILE* stdin; 1164 /// 1165 extern shared FILE* stdout; 1166 /// 1167 extern shared FILE* stderr; 1168 } 1169 else version (WASI) 1170 { 1171 // needs tail const 1172 extern shared FILE* stdin; 1173 /// 1174 extern shared FILE* stdout; 1175 /// 1176 extern shared FILE* stderr; 1177 enum 1178 { 1179 /// 1180 _IOFBF = 0, 1181 /// 1182 _IOLBF = 1, 1183 /// 1184 _IONBF = 2, 1185 } 1186 } 1187 else version (FreeStanding) 1188 { 1189 __gshared FILE* stdin; 1190 __gshared FILE* stdout; 1191 __gshared FILE* stderr; 1192 } 1193 else 1194 { 1195 static assert( false, "Unsupported platform" ); 1196 } 1197 1198 /// 1199 int remove(scope const char* filename); 1200 /// 1201 int rename(scope const char* from, scope const char* to); 1202 1203 /// 1204 @trusted FILE* tmpfile(); // No unsafe pointer manipulation. 1205 /// 1206 char* tmpnam(char* s); 1207 1208 /// 1209 int fclose(FILE* stream); 1210 1211 // No unsafe pointer manipulation. 1212 @trusted 1213 { 1214 /// 1215 int fflush(FILE* stream); 1216 } 1217 1218 /// 1219 FILE* fopen(scope const char* filename, scope const char* mode); 1220 /// 1221 FILE* freopen(scope const char* filename, scope const char* mode, FILE* stream); 1222 1223 /// 1224 void setbuf(FILE* stream, char* buf); 1225 /// 1226 int setvbuf(FILE* stream, char* buf, int mode, size_t size); 1227 1228 version (MinGW) 1229 { 1230 // Prefer the MinGW versions over the MSVC ones, as the latter don't handle 1231 // reals at all. 1232 /// 1233 pragma(printf) 1234 int __mingw_fprintf(FILE* stream, scope const char* format, scope const ...); 1235 /// 1236 alias __mingw_fprintf fprintf; 1237 1238 /// 1239 pragma(scanf) 1240 int __mingw_fscanf(FILE* stream, scope const char* format, scope ...); 1241 /// 1242 alias __mingw_fscanf fscanf; 1243 1244 /// 1245 pragma(printf) 1246 int __mingw_sprintf(scope char* s, scope const char* format, scope const ...); 1247 /// 1248 alias __mingw_sprintf sprintf; 1249 1250 /// 1251 pragma(scanf) 1252 int __mingw_sscanf(scope const char* s, scope const char* format, scope ...); 1253 /// 1254 alias __mingw_sscanf sscanf; 1255 1256 /// 1257 pragma(printf) 1258 int __mingw_vfprintf(FILE* stream, scope const char* format, va_list arg); 1259 /// 1260 alias __mingw_vfprintf vfprintf; 1261 1262 /// 1263 pragma(scanf) 1264 int __mingw_vfscanf(FILE* stream, scope const char* format, va_list arg); 1265 /// 1266 alias __mingw_vfscanf vfscanf; 1267 1268 /// 1269 pragma(printf) 1270 int __mingw_vsprintf(scope char* s, scope const char* format, va_list arg); 1271 /// 1272 alias __mingw_vsprintf vsprintf; 1273 1274 /// 1275 pragma(scanf) 1276 int __mingw_vsscanf(scope const char* s, scope const char* format, va_list arg); 1277 /// 1278 alias __mingw_vsscanf vsscanf; 1279 1280 /// 1281 pragma(printf) 1282 int __mingw_vprintf(scope const char* format, va_list arg); 1283 /// 1284 alias __mingw_vprintf vprintf; 1285 1286 /// 1287 pragma(scanf) 1288 int __mingw_vscanf(scope const char* format, va_list arg); 1289 /// 1290 alias __mingw_vscanf vscanf; 1291 1292 /// 1293 pragma(printf) 1294 int __mingw_printf(scope const char* format, scope const ...); 1295 /// 1296 alias __mingw_printf printf; 1297 1298 /// 1299 pragma(scanf) 1300 int __mingw_scanf(scope const char* format, scope ...); 1301 /// 1302 alias __mingw_scanf scanf; 1303 } 1304 else version (CRuntime_Glibc) 1305 { 1306 /// 1307 pragma(printf) 1308 int fprintf(FILE* stream, scope const char* format, scope const ...); 1309 /// 1310 pragma(scanf) 1311 int __isoc99_fscanf(FILE* stream, scope const char* format, scope ...); 1312 /// 1313 alias fscanf = __isoc99_fscanf; 1314 /// 1315 pragma(printf) 1316 int sprintf(scope char* s, scope const char* format, scope const ...); 1317 /// 1318 pragma(scanf) 1319 int __isoc99_sscanf(scope const char* s, scope const char* format, scope ...); 1320 /// 1321 alias sscanf = __isoc99_sscanf; 1322 /// 1323 pragma(printf) 1324 int vfprintf(FILE* stream, scope const char* format, va_list arg); 1325 /// 1326 pragma(scanf) 1327 int __isoc99_vfscanf(FILE* stream, scope const char* format, va_list arg); 1328 /// 1329 alias vfscanf = __isoc99_vfscanf; 1330 /// 1331 pragma(printf) 1332 int vsprintf(scope char* s, scope const char* format, va_list arg); 1333 /// 1334 pragma(scanf) 1335 int __isoc99_vsscanf(scope const char* s, scope const char* format, va_list arg); 1336 /// 1337 alias vsscanf = __isoc99_vsscanf; 1338 /// 1339 pragma(printf) 1340 int vprintf(scope const char* format, va_list arg); 1341 /// 1342 pragma(scanf) 1343 int __isoc99_vscanf(scope const char* format, va_list arg); 1344 /// 1345 alias vscanf = __isoc99_vscanf; 1346 /// 1347 pragma(printf) 1348 int printf(scope const char* format, scope const ...); 1349 /// 1350 pragma(scanf) 1351 int __isoc99_scanf(scope const char* format, scope ...); 1352 /// 1353 alias scanf = __isoc99_scanf; 1354 } 1355 else 1356 { 1357 /// 1358 pragma(printf) 1359 int fprintf(FILE* stream, scope const char* format, scope const ...); 1360 /// 1361 pragma(scanf) 1362 int fscanf(FILE* stream, scope const char* format, scope ...); 1363 /// 1364 pragma(printf) 1365 int sprintf(scope char* s, scope const char* format, scope const ...); 1366 /// 1367 pragma(scanf) 1368 int sscanf(scope const char* s, scope const char* format, scope ...); 1369 /// 1370 pragma(printf) 1371 int vfprintf(FILE* stream, scope const char* format, va_list arg); 1372 /// 1373 pragma(scanf) 1374 int vfscanf(FILE* stream, scope const char* format, va_list arg); 1375 /// 1376 pragma(printf) 1377 int vsprintf(scope char* s, scope const char* format, va_list arg); 1378 /// 1379 pragma(scanf) 1380 int vsscanf(scope const char* s, scope const char* format, va_list arg); 1381 /// 1382 pragma(printf) 1383 int vprintf(scope const char* format, va_list arg); 1384 /// 1385 pragma(scanf) 1386 int vscanf(scope const char* format, va_list arg); 1387 /// 1388 pragma(printf) 1389 int printf(scope const char* format, scope const ...); 1390 /// 1391 pragma(scanf) 1392 int scanf(scope const char* format, scope ...); 1393 } 1394 1395 // No unsafe pointer manipulation. 1396 @trusted 1397 { 1398 /// 1399 int fgetc(FILE* stream); 1400 /// 1401 int fputc(int c, FILE* stream); 1402 } 1403 1404 /// 1405 char* fgets(char* s, int n, FILE* stream); 1406 /// 1407 int fputs(scope const char* s, FILE* stream); 1408 /// 1409 char* gets(char* s); 1410 /// 1411 int puts(scope const char* s); 1412 1413 // No unsafe pointer manipulation. 1414 extern (D) @trusted 1415 { 1416 /// 1417 int getchar()() { return getc(stdin); } 1418 /// 1419 int putchar()(int c) { return putc(c,stdout); } 1420 } 1421 1422 /// 1423 alias getc = fgetc; 1424 /// 1425 alias putc = fputc; 1426 1427 /// 1428 @trusted int ungetc(int c, FILE* stream); // No unsafe pointer manipulation. 1429 1430 /// 1431 size_t fread(scope void* ptr, size_t size, size_t nmemb, FILE* stream); 1432 /// 1433 size_t fwrite(scope const void* ptr, size_t size, size_t nmemb, FILE* stream); 1434 1435 // No unsafe pointer manipulation. 1436 @trusted 1437 { 1438 /// 1439 int fgetpos(FILE* stream, scope fpos_t * pos); 1440 /// 1441 int fsetpos(FILE* stream, scope const fpos_t* pos); 1442 1443 /// 1444 int fseek(FILE* stream, c_long offset, int whence); 1445 /// 1446 c_long ftell(FILE* stream); 1447 } 1448 1449 version (CRuntime_DigitalMars) 1450 { 1451 // No unsafe pointer manipulation. 1452 extern (D) @trusted 1453 { 1454 /// 1455 void rewind()(FILE* stream) { fseek(stream,0L,SEEK_SET); stream._flag= stream._flag & ~_IOERR; } 1456 /// 1457 pure void clearerr()(FILE* stream) { stream._flag = stream._flag & ~(_IOERR|_IOEOF); } 1458 /// 1459 pure int feof()(FILE* stream) { return stream._flag&_IOEOF; } 1460 /// 1461 pure int ferror()(FILE* stream) { return stream._flag&_IOERR; } 1462 /// 1463 pure int fileno()(FILE* stream) { return stream._file; } 1464 } 1465 /// 1466 pragma(printf) 1467 int _snprintf(scope char* s, size_t n, scope const char* fmt, scope const ...); 1468 /// 1469 alias _snprintf snprintf; 1470 1471 /// 1472 pragma(printf) 1473 int _vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); 1474 /// 1475 alias _vsnprintf vsnprintf; 1476 1477 // 1478 // Digital Mars under-the-hood C I/O functions. Uses _iobuf* for the 1479 // unshared version of FILE*, usable when the FILE is locked. 1480 // 1481 1482 /// 1483 int _fputc_nlock(int c, _iobuf* fp); 1484 /// 1485 int _fputwc_nlock(int c, _iobuf* fp); 1486 /// 1487 int _fgetc_nlock(_iobuf* fp); 1488 /// 1489 int _fgetwc_nlock(_iobuf* fp); 1490 /// 1491 int __fp_lock(FILE* fp); 1492 /// 1493 void __fp_unlock(FILE* fp); 1494 /// 1495 int setmode(int fd, int mode); 1496 } 1497 else version (CRuntime_Microsoft) 1498 { 1499 // No unsafe pointer manipulation. 1500 @trusted 1501 { 1502 /// 1503 void rewind(FILE* stream); 1504 /// 1505 pure void clearerr(FILE* stream); 1506 /// 1507 pure int feof(FILE* stream); 1508 /// 1509 pure int ferror(FILE* stream); 1510 /// 1511 pure int fileno(FILE* stream); 1512 } 1513 1514 version (MinGW) 1515 { 1516 pragma(printf) 1517 int __mingw_snprintf(scope char* s, size_t n, scope const char* fmt, scope const ...); 1518 /// 1519 alias __mingw_snprintf _snprintf; 1520 /// 1521 alias __mingw_snprintf snprintf; 1522 1523 /// 1524 pragma(printf) 1525 int __mingw_vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); 1526 /// 1527 alias __mingw_vsnprintf _vsnprintf; 1528 /// 1529 alias __mingw_vsnprintf vsnprintf; 1530 } 1531 else 1532 { 1533 /// 1534 pragma(printf) 1535 int _snprintf(scope char* s, size_t n, scope const char* format, scope const ...); 1536 /// 1537 pragma(printf) 1538 int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); 1539 1540 /// 1541 pragma(printf) 1542 int _vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); 1543 /// 1544 pragma(printf) 1545 int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); 1546 } 1547 1548 // 1549 // Microsoft under-the-hood C I/O functions. Uses _iobuf* for the unshared 1550 // version of FILE*, usable when the FILE is locked. 1551 // 1552 import core.stdc.stddef : wchar_t; 1553 import core.stdc.wchar_ : wint_t; 1554 1555 /// 1556 int _fputc_nolock(int c, _iobuf* fp); 1557 /// 1558 int _fgetc_nolock(_iobuf* fp); 1559 /// 1560 wint_t _fputwc_nolock(wchar_t c, _iobuf* fp); 1561 /// 1562 wint_t _fgetwc_nolock(_iobuf* fp); 1563 /// 1564 void _lock_file(FILE* fp); 1565 /// 1566 void _unlock_file(FILE* fp); 1567 /// 1568 int _setmode(int fd, int mode); 1569 /// 1570 int _fseeki64(FILE* stream, long offset, int origin); 1571 /// 1572 long _ftelli64(FILE* stream); 1573 /// 1574 intptr_t _get_osfhandle(int fd); 1575 /// 1576 int _open_osfhandle(intptr_t osfhandle, int flags); 1577 } 1578 else version (CRuntime_Glibc) 1579 { 1580 // No unsafe pointer manipulation. 1581 @trusted 1582 { 1583 /// 1584 void rewind(FILE* stream); 1585 /// 1586 pure void clearerr(FILE* stream); 1587 /// 1588 pure int feof(FILE* stream); 1589 /// 1590 pure int ferror(FILE* stream); 1591 /// 1592 int fileno(FILE *); 1593 } 1594 1595 /// 1596 pragma(printf) 1597 int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); 1598 /// 1599 pragma(printf) 1600 int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); 1601 1602 // 1603 // Gnu under-the-hood C I/O functions. Uses _iobuf* for the unshared 1604 // version of FILE*, usable when the FILE is locked. 1605 // See http://gnu.org/software/libc/manual/html_node/I_002fO-on-Streams.html 1606 // 1607 import core.stdc.wchar_ : wint_t; 1608 import core.stdc.stddef : wchar_t; 1609 1610 /// 1611 int fputc_unlocked(int c, _iobuf* stream); 1612 /// 1613 int fgetc_unlocked(_iobuf* stream); 1614 /// 1615 wint_t fputwc_unlocked(wchar_t wc, _iobuf* stream); 1616 /// 1617 wint_t fgetwc_unlocked(_iobuf* stream); 1618 } 1619 else version (Darwin) 1620 { 1621 // No unsafe pointer manipulation. 1622 @trusted 1623 { 1624 /// 1625 void rewind(FILE*); 1626 /// 1627 pure void clearerr(FILE*); 1628 /// 1629 pure int feof(FILE*); 1630 /// 1631 pure int ferror(FILE*); 1632 /// 1633 int fileno(FILE*); 1634 } 1635 1636 /// 1637 pragma(printf) 1638 int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); 1639 /// 1640 pragma(printf) 1641 int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); 1642 } 1643 else version (FreeBSD) 1644 { 1645 // No unsafe pointer manipulation. 1646 @trusted 1647 { 1648 /// 1649 void rewind(FILE*); 1650 /// 1651 pure void clearerr(FILE*); 1652 /// 1653 pure int feof(FILE*); 1654 /// 1655 pure int ferror(FILE*); 1656 /// 1657 int fileno(FILE*); 1658 } 1659 1660 /// 1661 pragma(printf) 1662 int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); 1663 /// 1664 pragma(printf) 1665 int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); 1666 } 1667 else version (NetBSD) 1668 { 1669 // No unsafe pointer manipulation. 1670 @trusted 1671 { 1672 /// 1673 void rewind(FILE*); 1674 /// 1675 pure void clearerr(FILE*); 1676 /// 1677 pure int feof(FILE*); 1678 /// 1679 pure int ferror(FILE*); 1680 /// 1681 int fileno(FILE*); 1682 } 1683 1684 /// 1685 pragma(printf) 1686 int snprintf(char* s, size_t n, const scope char* format, scope const ...); 1687 /// 1688 pragma(printf) 1689 int vsnprintf(char* s, size_t n, const scope char* format, va_list arg); 1690 } 1691 else version (OpenBSD) 1692 { 1693 // No unsafe pointer manipulation. 1694 @trusted 1695 { 1696 /// 1697 void rewind(FILE*); 1698 } 1699 @trusted private 1700 { 1701 /// 1702 pragma(mangle, "clearerr") 1703 pure void __clearerr(FILE*); 1704 /// 1705 pragma(mangle, "feof") 1706 pure int __feof(FILE*); 1707 /// 1708 pragma(mangle, "ferror") 1709 pure int __ferror(FILE*); 1710 /// 1711 pragma(mangle, "fileno") 1712 int __fileno(FILE*); 1713 } 1714 1715 enum __SLBF = 0x0001; 1716 enum __SNBF = 0x0002; 1717 enum __SRD = 0x0004; 1718 enum __SWR = 0x0008; 1719 enum __SRW = 0x0010; 1720 enum __SEOF = 0x0020; 1721 enum __SERR = 0x0040; 1722 enum __SMBF = 0x0080; 1723 enum __SAPP = 0x0100; 1724 enum __SSTR = 0x0200; 1725 enum __SOPT = 0x0400; 1726 enum __SNPT = 0x0800; 1727 enum __SOFF = 0x1000; 1728 enum __SMOD = 0x2000; 1729 enum __SALC = 0x4000; 1730 enum __SIGN = 0x8000; 1731 1732 extern immutable __gshared int __isthreaded; 1733 1734 extern (D) @trusted 1735 { 1736 void __sclearerr()(FILE* p) 1737 { 1738 p._flags = p._flags & ~(__SERR|__SEOF); 1739 } 1740 1741 int __sfeof()(FILE* p) 1742 { 1743 return (p._flags & __SEOF) != 0; 1744 } 1745 1746 int __sferror()(FILE* p) 1747 { 1748 return (p._flags & __SERR) != 0; 1749 } 1750 1751 int __sfileno()(FILE* p) 1752 { 1753 return p._file; 1754 } 1755 1756 pure void clearerr()(FILE* file) 1757 { 1758 !__isthreaded ? __sclearerr(file) : __clearerr(file); 1759 } 1760 1761 pure int feof()(FILE* file) 1762 { 1763 return !__isthreaded ? __sfeof(file) : __feof(file); 1764 } 1765 1766 pure int ferror()(FILE* file) 1767 { 1768 return !__isthreaded ? __sferror(file) : __ferror(file); 1769 } 1770 1771 int fileno()(FILE* file) 1772 { 1773 return !__isthreaded ? __sfileno(file) : __fileno(file); 1774 } 1775 } 1776 1777 /// 1778 pragma(printf) 1779 int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); 1780 /// 1781 pragma(printf) 1782 int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); 1783 } 1784 else version (DragonFlyBSD) 1785 { 1786 // No unsafe pointer manipulation. 1787 @trusted 1788 { 1789 void rewind(FILE*); 1790 pure void clearerr(FILE*); 1791 pure int feof(FILE*); 1792 pure int ferror(FILE*); 1793 int fileno(FILE*); 1794 } 1795 enum __SLBF = 0x0001; 1796 enum __SNBF = 0x0002; 1797 enum __SRD = 0x0004; 1798 enum __SWR = 0x0008; 1799 enum __SRW = 0x0010; 1800 enum __SEOF = 0x0020; 1801 enum __SERR = 0x0040; 1802 enum __SMBF = 0x0080; 1803 enum __SAPP = 0x0100; 1804 enum __SSTR = 0x0200; 1805 enum __SOPT = 0x0400; 1806 enum __SNPT = 0x0800; 1807 enum __SOFF = 0x1000; 1808 enum __SMOD = 0x2000; 1809 enum __SALC = 0x4000; 1810 enum __SIGN = 0x8000; 1811 1812 pragma(printf) 1813 int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); 1814 pragma(printf) 1815 int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); 1816 } 1817 else version (Solaris) 1818 { 1819 // No unsafe pointer manipulation. 1820 @trusted 1821 { 1822 /// 1823 void rewind(FILE*); 1824 /// 1825 pure void clearerr(FILE*); 1826 /// 1827 pure int feof(FILE*); 1828 /// 1829 pure int ferror(FILE*); 1830 /// 1831 int fileno(FILE*); 1832 } 1833 1834 /// 1835 pragma(printf) 1836 int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); 1837 /// 1838 pragma(printf) 1839 int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); 1840 } 1841 else version (CRuntime_Bionic) 1842 { 1843 // No unsafe pointer manipulation. 1844 @trusted 1845 { 1846 /// 1847 void rewind(FILE*); 1848 /// 1849 pure void clearerr(FILE*); 1850 /// 1851 pure int feof(FILE*); 1852 /// 1853 pure int ferror(FILE*); 1854 /// 1855 int fileno(FILE*); 1856 } 1857 1858 /// 1859 pragma(printf) 1860 int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); 1861 /// 1862 pragma(printf) 1863 int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); 1864 } 1865 else version (CRuntime_Musl) 1866 { 1867 @trusted 1868 { 1869 /// 1870 void rewind(FILE* stream); 1871 /// 1872 pure void clearerr(FILE* stream); 1873 /// 1874 pure int feof(FILE* stream); 1875 /// 1876 pure int ferror(FILE* stream); 1877 /// 1878 int fileno(FILE *); 1879 } 1880 1881 /// 1882 pragma(printf) 1883 int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); 1884 /// 1885 pragma(printf) 1886 int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); 1887 } 1888 else version (CRuntime_UClibc) 1889 { 1890 // No unsafe pointer manipulation. 1891 @trusted 1892 { 1893 /// 1894 void rewind(FILE* stream); 1895 /// 1896 pure void clearerr(FILE* stream); 1897 /// 1898 pure int feof(FILE* stream); 1899 /// 1900 pure int ferror(FILE* stream); 1901 /// 1902 int fileno(FILE *); 1903 } 1904 1905 /// 1906 pragma(printf) 1907 int snprintf(scope char* s, size_t n, scope const char* format, scope const ...); 1908 /// 1909 pragma(printf) 1910 int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); 1911 } 1912 else version (WASI) 1913 { 1914 // No unsafe pointer manipulation. 1915 @trusted 1916 { 1917 /// 1918 void rewind(FILE* stream); 1919 /// 1920 pure void clearerr(FILE* stream); 1921 /// 1922 pure int feof(FILE* stream); 1923 /// 1924 pure int ferror(FILE* stream); 1925 /// 1926 int fileno(FILE *); 1927 } 1928 1929 /// 1930 int snprintf(scope char* s, size_t n, scope const char* format, ...); 1931 /// 1932 int vsnprintf(scope char* s, size_t n, scope const char* format, va_list arg); 1933 } 1934 else version (FreeStanding) 1935 { 1936 int snprintf(scope char* s, size_t n, scope const char* format, ...); 1937 } 1938 else 1939 { 1940 static assert( false, "Unsupported platform" ); 1941 } 1942 1943 /// 1944 void perror(scope const char* s); 1945 1946 version (CRuntime_DigitalMars) 1947 { 1948 version (none) 1949 import core.sys.windows.windows : HANDLE, _WaitSemaphore, _ReleaseSemaphore; 1950 else 1951 { 1952 // too slow to import windows 1953 private alias void* HANDLE; 1954 private void _WaitSemaphore(int iSemaphore); 1955 private void _ReleaseSemaphore(int iSemaphore); 1956 } 1957 1958 enum 1959 { 1960 /// 1961 FHND_APPEND = 0x04, 1962 /// 1963 FHND_DEVICE = 0x08, 1964 /// 1965 FHND_TEXT = 0x10, 1966 /// 1967 FHND_BYTE = 0x20, 1968 /// 1969 FHND_WCHAR = 0x40, 1970 } 1971 1972 private enum _MAX_SEMAPHORES = 10 + _NFILE; 1973 private enum _semIO = 3; 1974 1975 private extern __gshared short[_MAX_SEMAPHORES] _iSemLockCtrs; 1976 private extern __gshared int[_MAX_SEMAPHORES] _iSemThreadIds; 1977 private extern __gshared int[_MAX_SEMAPHORES] _iSemNestCount; 1978 private extern __gshared HANDLE[_NFILE] _osfhnd; 1979 extern shared ubyte[_NFILE] __fhnd_info; 1980 1981 // this is copied from semlock.h in DMC's runtime. 1982 private void LockSemaphore()(uint num) 1983 { 1984 asm nothrow @nogc 1985 { 1986 mov EDX, num; 1987 lock; 1988 inc _iSemLockCtrs[EDX * 2]; 1989 jz lsDone; 1990 push EDX; 1991 call _WaitSemaphore; 1992 add ESP, 4; 1993 } 1994 1995 lsDone: {} 1996 } 1997 1998 // this is copied from semlock.h in DMC's runtime. 1999 private void UnlockSemaphore()(uint num) 2000 { 2001 asm nothrow @nogc 2002 { 2003 mov EDX, num; 2004 lock; 2005 dec _iSemLockCtrs[EDX * 2]; 2006 js usDone; 2007 push EDX; 2008 call _ReleaseSemaphore; 2009 add ESP, 4; 2010 } 2011 2012 usDone: {} 2013 } 2014 2015 // This converts a HANDLE to a file descriptor in DMC's runtime 2016 /// 2017 int _handleToFD()(HANDLE h, int flags) 2018 { 2019 LockSemaphore(_semIO); 2020 scope(exit) UnlockSemaphore(_semIO); 2021 2022 foreach (fd; 0 .. _NFILE) 2023 { 2024 if (!_osfhnd[fd]) 2025 { 2026 _osfhnd[fd] = h; 2027 __fhnd_info[fd] = cast(ubyte)flags; 2028 return fd; 2029 } 2030 } 2031 2032 return -1; 2033 } 2034 2035 /// 2036 HANDLE _fdToHandle()(int fd) 2037 { 2038 // no semaphore is required, once inserted, a file descriptor 2039 // doesn't change. 2040 if (fd < 0 || fd >= _NFILE) 2041 return null; 2042 2043 return _osfhnd[fd]; 2044 } 2045 2046 enum 2047 { 2048 /// 2049 STDIN_FILENO = 0, 2050 /// 2051 STDOUT_FILENO = 1, 2052 /// 2053 STDERR_FILENO = 2, 2054 } 2055 2056 int open(scope const(char)* filename, int flags, ...); /// 2057 alias _open = open; /// 2058 int _wopen(scope const wchar* filename, int oflag, ...); /// 2059 int sopen(scope const char* filename, int oflag, int shflag, ...); /// 2060 alias _sopen = sopen; /// 2061 int _wsopen(scope const wchar* filename, int oflag, int shflag, ...); /// 2062 int close(int fd); /// 2063 alias _close = close; /// 2064 FILE *fdopen(int fd, scope const(char)* flags); /// 2065 alias _fdopen = fdopen; /// 2066 FILE *_wfdopen(int fd, scope const(wchar)* flags); /// 2067 2068 } 2069 else version (CRuntime_Microsoft) 2070 { 2071 int _open(scope const char* filename, int oflag, ...); /// 2072 int _wopen(scope const wchar* filename, int oflag, ...); /// 2073 int _sopen(scope const char* filename, int oflag, int shflag, ...); /// 2074 int _wsopen(scope const wchar* filename, int oflag, int shflag, ...); /// 2075 int _close(int fd); /// 2076 FILE *_fdopen(int fd, scope const(char)* flags); /// 2077 FILE *_wfdopen(int fd, scope const(wchar)* flags); /// 2078 } 2079 2080 version (Windows) 2081 { 2082 // file open flags 2083 enum 2084 { 2085 _O_RDONLY = 0x0000, /// 2086 O_RDONLY = _O_RDONLY, /// 2087 _O_WRONLY = 0x0001, /// 2088 O_WRONLY = _O_WRONLY, /// 2089 _O_RDWR = 0x0002, /// 2090 O_RDWR = _O_RDWR, /// 2091 _O_APPEND = 0x0008, /// 2092 O_APPEND = _O_APPEND, /// 2093 _O_CREAT = 0x0100, /// 2094 O_CREAT = _O_CREAT, /// 2095 _O_TRUNC = 0x0200, /// 2096 O_TRUNC = _O_TRUNC, /// 2097 _O_EXCL = 0x0400, /// 2098 O_EXCL = _O_EXCL, /// 2099 _O_TEXT = 0x4000, /// 2100 O_TEXT = _O_TEXT, /// 2101 _O_BINARY = 0x8000, /// 2102 O_BINARY = _O_BINARY, /// 2103 _O_WTEXT = 0x10000, /// 2104 _O_U16TEXT = 0x20000, /// 2105 _O_U8TEXT = 0x40000, /// 2106 _O_ACCMODE = (_O_RDONLY|_O_WRONLY|_O_RDWR), /// 2107 O_ACCMODE = _O_ACCMODE, /// 2108 _O_RAW = _O_BINARY, /// 2109 O_RAW = _O_BINARY, /// 2110 _O_NOINHERIT = 0x0080, /// 2111 O_NOINHERIT = _O_NOINHERIT, /// 2112 _O_TEMPORARY = 0x0040, /// 2113 O_TEMPORARY = _O_TEMPORARY, /// 2114 _O_SHORT_LIVED = 0x1000, /// 2115 _O_SEQUENTIAL = 0x0020, /// 2116 O_SEQUENTIAL = _O_SEQUENTIAL, /// 2117 _O_RANDOM = 0x0010, /// 2118 O_RANDOM = _O_RANDOM, /// 2119 } 2120 2121 enum 2122 { 2123 _S_IREAD = 0x0100, /// read permission, owner 2124 S_IREAD = _S_IREAD, /// read permission, owner 2125 _S_IWRITE = 0x0080, /// write permission, owner 2126 S_IWRITE = _S_IWRITE, /// write permission, owner 2127 } 2128 2129 enum 2130 { 2131 _SH_DENYRW = 0x10, /// deny read/write mode 2132 SH_DENYRW = _SH_DENYRW, /// deny read/write mode 2133 _SH_DENYWR = 0x20, /// deny write mode 2134 SH_DENYWR = _SH_DENYWR, /// deny write mode 2135 _SH_DENYRD = 0x30, /// deny read mode 2136 SH_DENYRD = _SH_DENYRD, /// deny read mode 2137 _SH_DENYNO = 0x40, /// deny none mode 2138 SH_DENYNO = _SH_DENYNO, /// deny none mode 2139 } 2140 }