The OpenD Programming Language

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 }