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